static void done_auth_entry(struct auth_entry *entry) { if (entry->box_item) done_listbox_item(&auth_browser, entry->box_item); done_uri(entry->uri); mem_free_if(entry->realm); mem_free_if(entry->nonce); mem_free_if(entry->opaque); mem_free(entry); }
/* @bookmark_class.setProperty */ static JSBool bookmark_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) { struct bookmark *bookmark; jsid tmp; unsigned char *title = NULL; unsigned char *url = NULL; int ok; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL)) return JS_FALSE; bookmark = JS_GetInstancePrivate(ctx, obj, (JSClass *) &bookmark_class, NULL); if (!bookmark) return JS_FALSE; if (!JSID_IS_INT(id)) return JS_FALSE; switch (JSID_TO_INT(id)) { case BOOKMARK_TITLE: if (!JS_ValueToId(ctx, *vp, &tmp)) return JS_FALSE; if (!jsval_to_bookmark_string(ctx, tmp, &title)) return JS_FALSE; break; case BOOKMARK_URL: if (!JS_ValueToId(ctx, *vp, &tmp)) return JS_FALSE; if (!jsval_to_bookmark_string(ctx, tmp, &url)) return JS_FALSE; break; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case. * Do the same here. */ return JS_TRUE; } ok = update_bookmark(bookmark, get_cp_index("UTF-8"), title, url); mem_free_if(title); mem_free_if(url); return ok ? JS_TRUE : JS_FALSE; }
void html_embed(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *type, *extension; unsigned char *object_src; /* This is just some dirty wrapper. We emulate various things through * this, which is anyway in the spirit of <object> element, unifying * <img> and <iframe> etc. */ object_src = get_url_val(a, (unsigned char *)"src", html_context->doc_cp); if (!object_src || !*object_src) { mem_free_set(&object_src, NULL); return; } /* If there is no extension we want to get the default mime/type * anyway? */ extension = (unsigned char *)strrchr((char *)object_src, '.'); if (!extension) extension = object_src; type = get_extension_content_type(extension); if (type && !c_strncasecmp((const char *)type, "image/", 6)) { html_img_do(a, object_src, html_context); } else { /* We will just emulate <iframe>. */ html_iframe_do(a, object_src, html_context); } mem_free_if(type); mem_free_set(&object_src, NULL); }
void done_document_options(struct document_options *options) { mem_free_if(options->framename); mem_free(options->image_link.prefix); mem_free(options->image_link.suffix); }
/* First information such as permissions is gathered for each directory entry. * Finally the sorted entries are added to the @data->fragment one by one. */ static inline void add_dir_entries(struct directory_entry *entries, unsigned char *dirpath, struct string *page) { unsigned char dircolor[8]; int dirpathlen = strlen((const char *)dirpath); int i; /* Setup @dircolor so it's easy to check if we should color dirs. */ if (get_opt_bool((const unsigned char *)"document.browse.links.color_dirs", NULL)) { color_to_string(get_opt_color((const unsigned char *)"document.colors.dirs", NULL), (unsigned char *) &dircolor); } else { dircolor[0] = 0; } for (i = 0; entries[i].name; i++) { add_dir_entry(&entries[i], page, dirpathlen, dircolor); mem_free(entries[i].attrib); mem_free(entries[i].name); } /* We may have allocated space for entries but added none. */ mem_free_if(entries); }
void html_source(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *src, *title; struct document_options *options = html_context->options; int display_style = options->image_link.display_style; src = get_url_val(a, "src", html_context->doc_cp); if (!src) return; title = get_attr_val(a, "title", html_context->doc_cp); if (!title || !*title) { if (display_style == 3) { mem_free_set(&title, get_image_filename_from_src(options->image_link.filename_maxlen, src)); } } html_focusable(html_context, a); if (title && *title) { put_link_line("Source: ", title, src, html_context->options->framename, html_context); } else { put_link_line("", "Source", src, html_context->options->framename, html_context); } mem_free_if(title); mem_free(src); }
/** First information such as permissions is gathered for each directory entry. * All entries are then sorted. */ static struct directory_entry * get_smb_directory_entries(int dir, struct string *prefix) { struct directory_entry *entries = NULL; int size = 0; struct smbc_dirent *entry; while ((entry = smbc_readdir(dir))) { struct stat st, *stp; struct directory_entry *new_entries; struct string attrib; struct string name; if (!strcmp(entry->name, ".")) continue; new_entries = mem_realloc(entries, (size + 2) * sizeof(*new_entries)); if (!new_entries) continue; entries = new_entries; if (!init_string(&attrib)) { continue; } if (!init_string(&name)) { done_string(&attrib); continue; } add_string_to_string(&name, prefix); add_to_string(&name, entry->name); stp = (smbc_stat(name.source, &st)) ? NULL : &st; stat_type(&attrib, stp); stat_mode(&attrib, stp); stat_links(&attrib, stp); stat_user(&attrib, stp); stat_group(&attrib, stp); stat_size(&attrib, stp); stat_date(&attrib, stp); entries[size].name = stracpy(entry->name); entries[size].attrib = attrib.source; done_string(&name); size++; } smbc_closedir(dir); if (!size) { /* We may have allocated space for entries but added none. */ mem_free_if(entries); return NULL; } qsort(entries, size, sizeof(*entries), compare_dir_entries); memset(&entries[size], 0, sizeof(*entries)); return entries; }
void done_dom_stack(struct dom_stack *stack) { int i; assert(stack); for (i = 0; i < stack->contexts_size; i++) { mem_free_if(stack->contexts[i]->state_objects); mem_free(stack->contexts[i]); } mem_free_if(stack->contexts); mem_free_if(stack->states); memset(stack, 0, sizeof(*stack)); }
/** Allocates a line_info table describing the layout of the textarea buffer. * * @param text the text to format; must be in a unibyte charset * @param width is max width and the offset at which @a text will be * wrapped * @param wrap controls how the wrapping of @a text is performed * @param format is non zero the @a text will be modified to make it * suitable for encoding it for form posting */ static struct line_info * format_text(unsigned char *text, int width, enum form_wrap wrap, int format) { struct line_info *line = NULL; int line_number = 0; int begin = 0; int pos = 0; int skip; assert(text); if_assert_failed return NULL; /* Allocate the ending entries */ if (!realloc_line_info(&line, 0)) return NULL; while (text[pos]) { if (text[pos] == '\n') { skip = 1; } else if (wrap == FORM_WRAP_NONE || pos - begin < width) { pos++; continue; } else { unsigned char *wrappos; /* Find a place to wrap the text */ wrappos = memrchr(&text[begin], ' ', pos - begin); if (wrappos) { /* When formatting text for form submitting we * have to apply the wrapping mode. */ if (wrap == FORM_WRAP_HARD && format) *wrappos = '\n'; pos = wrappos - text; } skip = !!wrappos; } if (!realloc_line_info(&line, line_number)) { mem_free_if(line); return NULL; } line[line_number].start = begin; line[line_number++].end = pos; begin = pos += skip; } /* Flush the last text before the loop ended */ line[line_number].start = begin; line[line_number++].end = pos; /* Add end marker */ line[line_number].start = line[line_number].end = -1; return line; }
static void free_itrm(struct itrm *itrm) { if (!itrm) return; if (!itrm->remote) { if (itrm->orig_title && *itrm->orig_title) { set_window_title(itrm->orig_title, itrm->title_codepage); } else if (itrm->touched_title) { /* Set the window title to the value of $TERM if X11 * wasn't compiled in. Should hopefully make at least * half the users happy. (debian bug #312955) */ unsigned char title[MAX_TERM_LEN]; get_terminal_name(title); if (*title) set_window_title(title, get_cp_index("US-ASCII")); } unhandle_terminal_resize(itrm->in.ctl); #ifdef CONFIG_MOUSE disable_mouse(); #endif send_done_sequence(itrm->out.std, itrm->altscreen); tcsetattr(itrm->in.ctl, TCSANOW, &itrm->t); } mem_free_set(&itrm->orig_title, NULL); /* elinks -remote may not have a valid stdin if not run from a tty (bug 938) */ if (!itrm->remote || itrm->in.std >= 0) clear_handlers(itrm->in.std); clear_handlers(itrm->in.sock); clear_handlers(itrm->out.std); clear_handlers(itrm->out.sock); kill_timer(&itrm->timer); if (itrm == ditrm) ditrm = NULL; mem_free_if(itrm->out.queue.data); mem_free_if(itrm->in.queue.data); mem_free(itrm); }
static void done_connection_info(struct socket *socket) { struct connect_info *connect_info = socket->connect_info; assert(socket->connect_info); if (connect_info->dnsquery) kill_dns_request(&connect_info->dnsquery); mem_free_if(connect_info->addr); done_uri(connect_info->uri); mem_free_set(&socket->connect_info, NULL); }
static unsigned char * deflate_decode_buffer(struct stream_encoded *st, int window_size, unsigned char *data, int len, int *new_len) { struct deflate_enc_data *enc_data = (struct deflate_enc_data *) st->data; z_stream *stream = &enc_data->deflate_stream; unsigned char *buffer = NULL; int error; *new_len = 0; /* default, left there if an error occurs */ if (!len) return NULL; stream->next_in = data; stream->avail_in = len; stream->total_out = 0; do { unsigned char *new_buffer; size_t size = stream->total_out + MAX_STR_LEN; new_buffer = mem_realloc(buffer, size); if (!new_buffer) { error = Z_MEM_ERROR; break; } buffer = new_buffer; stream->next_out = buffer + stream->total_out; stream->avail_out = MAX_STR_LEN; error = inflate(stream, Z_SYNC_FLUSH); if (error == Z_STREAM_END) { break; } } while (error == Z_OK && stream->avail_in > 0); if (error == Z_STREAM_END) { inflateEnd(stream); enc_data->after_end = 1; error = Z_OK; } if (error == Z_OK) { *new_len = stream->total_out; return buffer; } else { mem_free_if(buffer); return NULL; } }
void html_object(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *type, *url; /* This is just some dirty wrapper. We emulate various things through * this, which is anyway in the spirit of <object> element, unifying * <img> and <iframe> etc. */ url = get_url_val(a, (unsigned char *)"data", html_context->doc_cp); if (!url) url = get_url_val(a, (unsigned char *)"codebase", html_context->doc_cp); if (!url) return; type = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp); if (!type) { mem_free(url); return; } if (!c_strncasecmp((const char *)type, "text/", 5)) { /* We will just emulate <iframe>. */ html_iframe_do(a, url, html_context); html_skip(html_context, a); } else if (!c_strncasecmp((const char *)type, "image/", 6)) { /* <img> emulation. */ /* TODO: Use the enclosed text as 'alt' attribute. */ html_img_do(a, url, html_context); } else { unsigned char *name; name = get_attr_val(a, (unsigned char *)"standby", html_context->doc_cp); html_focusable(html_context, a); if (name && *name) { put_link_line((unsigned char *)"Object: ", name, url, html_context->options->framename, html_context); } else { put_link_line((unsigned char *)"Object: ", type, url, html_context->options->framename, html_context); } mem_free_if(name); } mem_free(type); mem_free(url); }
static void brotli_close(struct stream_encoded *stream) { struct br_enc_data *data = (struct br_enc_data *) stream->data; if (data) { BrotliStateCleanup(&data->br_stream); if (data->fdread != -1) { close(data->fdread); } if (data->need_free) { mem_free_if(data->output); } mem_free(data); stream->data = 0; } }
static void html_link_clear(struct hlink *link) { assert(link); mem_free_if(link->content_type); mem_free_if(link->media); mem_free_if(link->href); mem_free_if(link->hreflang); mem_free_if(link->title); mem_free_if(link->lang); mem_free_if(link->name); memset(link, 0, sizeof(*link)); }
unsigned char * encode_textarea(struct submitted_value *sv) { struct form_control *fc; void *blabla; assert(sv && sv->value); if_assert_failed return NULL; fc = sv->form_control; /* We need to reformat text now if it has to be wrapped hard, just * before encoding it. */ /* TODO: Do we need here UTF-8 format or not? --scrool */ blabla = format_text(sv->value, fc->cols, fc->wrap, 1); mem_free_if(blabla); return encode_crlf(sv); }
struct uri * get_proxy_uri(struct uri *uri, struct connection_state *error_state) { if (uri->protocol == PROTOCOL_PROXY) { return get_composed_uri(uri, URI_BASE); } else { #ifdef CONFIG_SCRIPTING unsigned char *tmp = NULL; static int get_proxy_event_id = EVENT_NONE; set_event_id(get_proxy_event_id, "get-proxy"); trigger_event(get_proxy_event_id, &tmp, struri(uri)); uri = get_proxy_worker(uri, tmp, error_state); mem_free_if(tmp); return uri; #else return get_proxy_worker(uri, NULL, error_state); #endif } }
void html_base(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *al; al = get_url_val(a, (unsigned char *)"href", html_context->doc_cp); if (al) { unsigned char *base = join_urls(html_context->base_href, al); struct uri *uri = base ? get_uri(base, 0) : NULL; mem_free(al); mem_free_if(base); if (uri) { done_uri(html_context->base_href); html_context->base_href = uri; } } al = get_target(html_context->options, a); if (al) mem_free_set(&html_context->base_target, al); }
void done_dom_stack_context(struct dom_stack *stack, struct dom_stack_context *context) { size_t i; mem_free_if(context->state_objects); mem_free(context); /* Handle the trivial case of temporary contexts optimally by iteration last added first. */ for (i = stack->contexts_size - 1; i >= 0; i--) { if (stack->contexts[i] != context) continue; stack->contexts_size--; if (i < stack->contexts_size) { struct dom_stack_context **pos = &stack->contexts[i]; size_t size = stack->contexts_size - i; memmove(pos, pos + 1, size * sizeof(*pos)); } break; } }
void html_applet(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *code, *alt; code = get_url_val(a, (unsigned char *)"code", html_context->doc_cp); if (!code) return; alt = get_attr_val(a, (unsigned char *)"alt", html_context->doc_cp); html_focusable(html_context, a); if (alt && *alt) { put_link_line((unsigned char *)"Applet: ", alt, code, html_context->options->framename, html_context); } else { put_link_line((unsigned char *)"", (unsigned char *)"Applet", code, html_context->options->framename, html_context); } mem_free_if(alt); mem_free(code); }
/* Return -1 on error, 0 or success. */ int ssl_connect(struct socket *socket) { int ret; unsigned char *server_name; struct connection *conn = (struct connection *)socket->conn; /* TODO: Recode server_name to UTF-8. */ server_name = get_uri_string(conn->proxied_uri, URI_HOST); if (!server_name) { socket->ops->done(socket, connection_state(S_OUT_OF_MEM)); return -1; } /* RFC 3546 says literal IPv4 and IPv6 addresses are not allowed. */ if (is_ip_address(server_name, strlen((const char *)server_name))) mem_free_set(&server_name, NULL); if (init_ssl_connection(socket, server_name) == S_SSL_ERROR) { mem_free_if(server_name); socket->ops->done(socket, connection_state(S_SSL_ERROR)); return -1; } mem_free_if(server_name); if (socket->no_tls) ssl_set_no_tls(socket); #ifdef USE_OPENSSL SSL_set_fd((SSL *)socket->ssl, socket->fd); if (get_opt_bool((const unsigned char *)"connection.ssl.cert_verify", NULL)) SSL_set_verify((SSL *)socket->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); if (get_opt_bool((const unsigned char *)"connection.ssl.client_cert.enable", NULL)) { unsigned char *client_cert; #ifdef CONFIG_NSS_COMPAT_OSSL client_cert = get_opt_str( (const unsigned char *)"connection.ssl.client_cert.nickname", NULL); #else client_cert = get_opt_str( (const unsigned char *)"connection.ssl.client_cert.file", NULL); #endif if (!*client_cert) { client_cert = (unsigned char *)getenv("X509_CLIENT_CERT"); if (client_cert && !*client_cert) client_cert = NULL; } if (client_cert) { #ifdef CONFIG_NSS_COMPAT_OSSL SSL_CTX_use_certificate_chain_file( (SSL *) socket->ssl, (const char *)client_cert); #else SSL_CTX *ctx = ((SSL *) socket->ssl)->ctx; SSL_CTX_use_certificate_chain_file(ctx, (const char *)client_cert); SSL_CTX_use_PrivateKey_file(ctx, (const char *)client_cert, SSL_FILETYPE_PEM); #endif } } #elif defined(CONFIG_GNUTLS) /* GnuTLS uses function pointers for network I/O. The default * functions take a file descriptor, but it must be passed in * as a pointer. GnuTLS uses the GNUTLS_INT_TO_POINTER and * GNUTLS_POINTER_TO_INT macros for these conversions, but * those are unfortunately not in any public header. So * ELinks must just cast the pointer the best it can and hope * that the conversions match. */ gnutls_transport_set_ptr(*((ssl_t *) socket->ssl), (gnutls_transport_ptr_t) (longptr_T) socket->fd); /* TODO: Some certificates fuss. --pasky */ #endif ret = ssl_do_connect(socket); switch (ret) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ2: socket->ops->set_state(socket, connection_state(S_SSL_NEG)); set_handlers(socket->fd, (select_handler_T) ssl_want_read, NULL, (select_handler_T) dns_exception, socket); return -1; case SSL_ERROR_NONE: #ifdef CONFIG_GNUTLS if (!get_opt_bool((const unsigned char *)"connection.ssl.cert_verify", NULL)) break; if (!verify_certificates(socket)) #endif break; default: if (ret != SSL_ERROR_NONE) { /* DBG("sslerr %s", gnutls_strerror(ret)); */ socket->no_tls = !socket->no_tls; } connect_socket(socket, connection_state(S_SSL_ERROR)); return -1; } return 0; }
static enum parse_error parse_bind(struct option *opt_tree, struct conf_parsing_state *state, struct string *mirror, int is_system_conf) { unsigned char *keymap, *keystroke, *action; enum parse_error err = ERROR_NONE; struct conf_parsing_pos before_error; skip_white(&state->pos); if (!*state->pos.look) return show_parse_error(state, ERROR_PARSE); /* Keymap */ before_error = state->pos; keymap = option_types[OPT_STRING].read(NULL, &state->pos.look, &state->pos.line); skip_white(&state->pos); if (!keymap || !*state->pos.look) { state->pos = before_error; return show_parse_error(state, ERROR_PARSE); } /* Keystroke */ before_error = state->pos; keystroke = option_types[OPT_STRING].read(NULL, &state->pos.look, &state->pos.line); skip_white(&state->pos); if (!keystroke || !*state->pos.look) { mem_free(keymap); mem_free_if(keystroke); state->pos = before_error; return show_parse_error(state, ERROR_PARSE); } /* Equal sign */ skip_white(&state->pos); if (*state->pos.look != '=') { mem_free(keymap); mem_free(keystroke); return show_parse_error(state, ERROR_PARSE); } state->pos.look++; /* '=' */ skip_white(&state->pos); if (!*state->pos.look) { mem_free(keymap); mem_free(keystroke); return show_parse_error(state, ERROR_PARSE); } /* Action */ before_error = state->pos; action = option_types[OPT_STRING].read(NULL, &state->pos.look, &state->pos.line); if (!action) { mem_free(keymap); mem_free(keystroke); state->pos = before_error; return show_parse_error(state, ERROR_PARSE); } if (!mirror) { /* loading a configuration file */ /* We don't bother to bind() if -default-keys. */ if (!get_cmd_opt_bool("default-keys") && bind_do(keymap, keystroke, action, is_system_conf)) { /* bind_do() tried but failed. */ err = show_parse_error(state, ERROR_VALUE); } else { err = ERROR_NONE; } } else if (is_system_conf) { /* scanning a file that will not be rewritten */ /* TODO */ } else { /* rewriting a configuration file */ /* Mirror what we already have. If the keystroke has * been unbound, then act_str is simply "none" and * this does not require special handling. */ unsigned char *act_str = bind_act(keymap, keystroke); if (act_str) { add_bytes_to_string(mirror, state->mirrored, before_error.look - state->mirrored); add_to_string(mirror, act_str); mem_free(act_str); state->mirrored = state->pos.look; } else { err = show_parse_error(state, ERROR_VALUE); } } mem_free(keymap); mem_free(keystroke); mem_free(action); return err; }
static void do_html_select(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, struct html_context *html_context) { struct conv_table *ct = (struct conv_table *)html_context->special_f(html_context, SP_TABLE, NULL); struct form_control *fc; struct string lbl = NULL_STRING, orig_lbl = NULL_STRING; unsigned char **values = NULL; unsigned char **labels; unsigned char *name, *t_attr, *en; int namelen; int nnmi = 0; int order = 0; int preselect = -1; int group = 0; int i, max_width; int closing_tag; html_focusable(html_context, attr); init_menu(&lnk_menu); se: en = html; see: html = en; while (html < eof && *html != '<') html++; if (html >= eof) { abort: *end = html; if (lbl.source) done_string(&lbl); if (orig_lbl.source) done_string(&orig_lbl); if (values) { int j; for (j = 0; j < order; j++) mem_free_if(values[j]); mem_free(values); } destroy_menu(&lnk_menu); *end = en; return; } if (lbl.source) { unsigned char *q, *s = en; int l = html - en; while (l && isspace(s[0])) s++, l--; while (l && isspace(s[l-1])) l--; q = convert_string(ct, s, l, html_context->options->cp, CSM_DEFAULT, NULL, NULL, NULL); if (q) add_to_string(&lbl, q), mem_free(q); add_bytes_to_string(&orig_lbl, s, l); } if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) { html = skip_comment(html, eof); goto se; } if (parse_element(html, eof, &name, &namelen, &t_attr, &en)) { html++; goto se; } if (!namelen) goto see; if (name[0] == '/') { namelen--; if (!namelen) goto see; name++; closing_tag = 1; } else { closing_tag = 0; } if (closing_tag && !c_strlcasecmp(name, namelen, (const unsigned char *)"SELECT", 6)) { add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi); goto end_parse; } if (!c_strlcasecmp(name, namelen, (const unsigned char *)"OPTION", 6)) { add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi); if (!closing_tag) { unsigned char *value, *label; if (has_attr(t_attr, (unsigned char *)"disabled", html_context->doc_cp)) goto see; if (preselect == -1 && has_attr(t_attr, (unsigned char *)"selected", html_context->doc_cp)) preselect = order; value = get_attr_val(t_attr, (unsigned char *)"value", html_context->doc_cp); if (!mem_align_alloc(&values, order, order + 1, 0xFF)) goto abort; values[order++] = value; label = get_attr_val(t_attr, (unsigned char *)"label", html_context->doc_cp); if (label) new_menu_item(&lnk_menu, label, order - 1, 0); if (!value || !label) { init_string(&lbl); init_string(&orig_lbl); nnmi = !!label; } } goto see; } if (!c_strlcasecmp(name, namelen, (const unsigned char *)"OPTGROUP", 8)) { add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi); if (group) new_menu_item(&lnk_menu, NULL, -1, 0), group = 0; if (!closing_tag) { unsigned char *label; label = get_attr_val(t_attr, (unsigned char *)"label", html_context->doc_cp); if (!label) { label = stracpy((const unsigned char *)""); if (!label) goto see; } new_menu_item(&lnk_menu, label, -1, 0); group = 1; } } goto see; end_parse: *end = en; if (!order) goto abort; labels = (unsigned char **)mem_calloc(order, sizeof(unsigned char *)); if (!labels) goto abort; fc = init_form_control(FC_SELECT, attr, html_context); if (!fc) { mem_free(labels); goto abort; } fc->id = get_attr_val(attr, (unsigned char *)"id", html_context->doc_cp); fc->name = get_attr_val(attr, (unsigned char *)"name", html_context->doc_cp); fc->default_state = preselect < 0 ? 0 : preselect; fc->default_value = order ? stracpy(values[fc->default_state]) : stracpy((const unsigned char *)""); fc->nvalues = order; fc->values = values; fc->menu = detach_menu(&lnk_menu); fc->labels = labels; menu_labels(fc->menu, (unsigned char *)"", labels); put_chrs(html_context, (unsigned char *)"[", 1); html_stack_dup(html_context, ELEMENT_KILLABLE); format.form = fc; format.style.attr |= AT_BOLD; max_width = 0; for (i = 0; i < order; i++) { if (!labels[i]) continue; #ifdef CONFIG_UTF8 if (html_context->options->utf8) int_lower_bound(&max_width, utf8_ptr2cells(labels[i], NULL)); else #endif /* CONFIG_UTF8 */ int_lower_bound(&max_width, strlen((const char *)labels[i])); } for (i = 0; i < max_width; i++) put_chrs(html_context, (unsigned char *)"_", 1); pop_html_element(html_context); put_chrs(html_context, (unsigned char *)"]", 1); html_context->special_f(html_context, SP_CONTROL, fc); }
static void smb_got_header(struct socket *socket, struct read_buffer *rb) { struct connection *conn = socket->conn; struct read_buffer *buf; int error = 0; conn->cached = get_cache_entry(conn->uri); if (!conn->cached) { /* Even though these are pipes rather than real * sockets, call close_socket instead of close, to * ensure that abort_connection won't try to close the * file descriptors again. (Could we skip the calls * and assume abort_connection will do them?) */ close_socket(socket); close_socket(conn->data_socket); abort_connection(conn, connection_state(S_OUT_OF_MEM)); return; } socket->state = SOCKET_END_ONCLOSE; if (rb->length > 0) { unsigned char *ctype = memacpy(rb->data, rb->length); if (ctype && *ctype) { if (!strcmp(ctype, "text/x-error")) { error = 1; mem_free(ctype); } else { if (ctype[0] >= '0' && ctype[0] <= '9') { #ifdef HAVE_ATOLL conn->est_length = (off_t)atoll(ctype); #else conn->est_length = (off_t)atol(ctype); #endif mem_free(ctype); /* avoid error */ if (!conn->est_length) { abort_connection(conn, connection_state(S_OK)); return; } } else mem_free_set(&conn->cached->content_type, ctype); } } else { mem_free_if(ctype); } } buf = alloc_read_buffer(conn->data_socket); if (!buf) { close_socket(socket); close_socket(conn->data_socket); abort_connection(conn, connection_state(S_OUT_OF_MEM)); return; } if (error) { mem_free_set(&conn->cached->content_type, stracpy("text/html")); read_from_socket(conn->data_socket, buf, connection_state(S_CONN), smb_got_error); } else { read_from_socket(conn->data_socket, buf, connection_state(S_CONN), smb_got_data); } }
void menu_keys(struct terminal *term, void *d_, void *xxx) { /* [gettext_accelerator_context(menu_keys)] */ int d = (long) d_; /* We scale by main mapping because it has the most actions */ action_id_T action_ids[MAIN_ACTIONS] = { ACT_MAIN_MENU, ACT_MAIN_QUIT, ACT_MAIN_MOVE_LINK_NEXT, ACT_MAIN_MOVE_LINK_PREV, ACT_MAIN_SCROLL_DOWN, ACT_MAIN_SCROLL_UP, ACT_MAIN_SCROLL_LEFT, ACT_MAIN_SCROLL_RIGHT, ACT_MAIN_HISTORY_MOVE_BACK, ACT_MAIN_GOTO_URL, ACT_MAIN_GOTO_URL_CURRENT, ACT_MAIN_DOCUMENT_INFO, ACT_MAIN_HEADER_INFO, ACT_MAIN_SEARCH, ACT_MAIN_SEARCH_BACK, ACT_MAIN_FIND_NEXT, ACT_MAIN_FIND_NEXT_BACK, ACT_MAIN_LINK_FOLLOW, ACT_MAIN_LINK_DOWNLOAD, ACT_MAIN_TOGGLE_HTML_PLAIN, ACT_MAIN_NONE, }; struct string keys; struct keys_toggle_info *info; info = (struct keys_toggle_info *)mem_calloc(1, sizeof(*info)); if (!info || !init_string(&keys)) { mem_free_if(info); return; } info->term = term; info->toggle = d; if (info->toggle) { int action_id; int keymap_id; for (action_id = 0; action_id < MAIN_ACTIONS - 1; action_id++) { action_ids[action_id] = action_id + 1; } for (keymap_id = 0; keymap_id < KEYMAP_MAX; keymap_id++) { add_actions_to_string(&keys, action_ids, keymap_id, term); if (keymap_id + 1 < KEYMAP_MAX) add_to_string(&keys, (const unsigned char *)"\n\n"); /* Just a little reminder that the following code takes * the easy way. */ assert((int) MAIN_ACTIONS > (int) EDIT_ACTIONS); assert((int) EDIT_ACTIONS > (int) MENU_ACTIONS); if (keymap_id == KEYMAP_MAIN) { action_ids[EDIT_ACTIONS] = ACT_EDIT_NONE; } else if (keymap_id == KEYMAP_EDIT) { action_ids[MENU_ACTIONS] = ACT_MENU_NONE; } } } else { add_actions_to_string(&keys, action_ids, KEYMAP_MAIN, term); } msg_box(term, getml(info, (void *) NULL), MSGBOX_FREE_TEXT | MSGBOX_SCROLLABLE, N_("Keys"), ALIGN_LEFT, keys.source, info, 2, MSG_BOX_BUTTON(N_("~OK"), NULL, B_ENTER | B_ESC), MSG_BOX_BUTTON(N_("~Toggle display"), push_toggle_keys_display_button, B_ENTER)); }
void html_form(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *al; struct form *form; html_context->was_br = 1; form = init_form(); if (!form) return; form->method = FORM_METHOD_GET; form->form_num = a - html_context->startf; al = get_attr_val(a, (unsigned char *)"method", html_context->doc_cp); if (al) { if (!c_strcasecmp((const char *)al, "post")) { unsigned char *enctype; enctype = get_attr_val(a, (unsigned char *)"enctype", html_context->doc_cp); form->method = FORM_METHOD_POST; if (enctype) { if (!c_strcasecmp((const char *)enctype, "multipart/form-data")) form->method = FORM_METHOD_POST_MP; else if (!c_strcasecmp((const char *)enctype, "text/plain")) form->method = FORM_METHOD_POST_TEXT_PLAIN; mem_free(enctype); } } mem_free(al); } form->onsubmit = get_attr_val(a, (unsigned char *)"onsubmit", html_context->doc_cp); al = get_attr_val(a, (unsigned char *)"name", html_context->doc_cp); if (al) form->name = al; al = get_attr_val(a, (unsigned char *)"action", html_context->doc_cp); /* The HTML specification at * http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.3 states * that the behavior of an empty action attribute should be undefined. * Mozilla handles action="" as action="<current-URI>" which seems * reasonable. (bug 615) */ if (al && *al) { form->action = join_urls(html_context->base_href, trim_chars(al, ' ', NULL)); mem_free(al); } else { enum uri_component components = URI_ORIGINAL; mem_free_if(al); /* We have to do following for GET method, because we would end * up with two '?' otherwise. */ if (form->method == FORM_METHOD_GET) components = URI_FORM_GET; form->action = get_uri_string(html_context->base_href, components); /* No action URI should contain post data */ assert(!form->action || !strchr((char *)form->action, POST_CHAR)); /* GET method URIs should not have '?'. */ assert(!form->action || form->method != FORM_METHOD_GET || !strchr((char *)form->action, '?')); } al = get_target(html_context->options, a); form->target = al ? al : stracpy(html_context->base_target); html_context->special_f(html_context, SP_FORM, form); }
/** Allocates a line_info table describing the layout of the textarea buffer. * * @param text the text to format; must be in UTF-8 * @param width is max width and the offset at which @a text will be * wrapped * @param wrap controls how the wrapping of @a text is performed * @param format is non zero the @a text will be modified to make it * suitable for encoding it for form posting */ static struct line_info * format_textutf8(unsigned char *text, int width, enum form_wrap wrap, int format) { struct line_info *line = NULL; int line_number = 0; int begin = 0; int pos = 0; unsigned char *text_end; int skip; unsigned char *wrappos=NULL; int chars_cells=0; /* Number of console chars on line */ assert(text); if_assert_failed return NULL; /* Allocate the ending entries */ if (!realloc_line_info(&line, 0)) return NULL; text_end = text + strlen(text); while (text[pos]) { int char_cells = utf8_char2cells(&text[pos], text_end); if (text[pos] == ' ') wrappos = &text[pos]; if (text[pos] == '\n') { skip = 1; } else if (wrap == FORM_WRAP_NONE || chars_cells + char_cells < width) { pos += utf8charlen(&text[pos]); chars_cells += char_cells; continue; } else { if (wrappos) { /* When formatting text for form submitting we * have to apply the wrapping mode. */ if (wrap == FORM_WRAP_HARD && format) *wrappos = '\n'; pos = wrappos - text; } skip = !!wrappos; } if (!realloc_line_info(&line, line_number)) { mem_free_if(line); return NULL; } line[line_number].last_char_width = char_cells; line[line_number].split_next = !skip; line[line_number].start = begin; line[line_number++].end = pos; line[line_number].split_prev = !skip; begin = pos += skip; chars_cells = 0; wrappos = NULL; } line[line_number].split_next = 0; /* Flush the last text before the loop ended */ line[line_number].start = begin; line[line_number++].end = pos; /* Add end marker */ line[line_number].start = line[line_number].end = -1; line[line_number].split_next = line[line_number].split_prev = 0; line[0].split_prev = 0; return line; }
void html_option(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { struct form_control *fc; unsigned char *val; if (!format.select) return; val = get_attr_val(a, (unsigned char *)"value", html_context->doc_cp); if (!val) { struct string str; unsigned char *p, *r; unsigned char *name; int namelen; for (p = a - 1; *p != '<'; p--); if (!init_string(&str)) goto end_parse; if (parse_element(p, html_context->eoff, NULL, NULL, NULL, &p)) { INTERNAL("parse element failed"); val = str.source; goto end_parse; } se: while (p < html_context->eoff && isspace(*p)) p++; while (p < html_context->eoff && !isspace(*p) && *p != '<') { sp: add_char_to_string(&str, *p ? *p : ' '), p++; } r = p; val = str.source; /* Has to be before the possible 'goto end_parse' */ while (r < html_context->eoff && isspace(*r)) r++; if (r >= html_context->eoff) goto end_parse; if (r - 2 <= html_context->eoff && (r[1] == '!' || r[1] == '?')) { p = skip_comment(r, html_context->eoff); goto se; } if (parse_element(r, html_context->eoff, &name, &namelen, NULL, &p)) goto sp; if (namelen < 6) goto se; if (name[0] == '/') name++, namelen--; if (c_strlcasecmp(name, namelen, (const unsigned char *)"OPTION", 6) && c_strlcasecmp(name, namelen, (const unsigned char *)"SELECT", 6) && c_strlcasecmp(name, namelen, (const unsigned char *)"OPTGROUP", 8)) goto se; } end_parse: fc = init_form_control(FC_CHECKBOX, a, html_context); if (!fc) { mem_free_if(val); return; } fc->id = get_attr_val(a, (unsigned char *)"id", html_context->doc_cp); fc->name = null_or_stracpy(format.select); fc->default_value = val; fc->default_state = has_attr(a, (unsigned char *)"selected", html_context->doc_cp); fc->mode = has_attr(a, (unsigned char *)"disabled", html_context->doc_cp) ? FORM_MODE_DISABLED : format.select_disabled; put_chrs(html_context, (unsigned char *)" ", 1); html_stack_dup(html_context, ELEMENT_KILLABLE); format.form = fc; format.style.attr |= AT_BOLD; put_chrs(html_context, (unsigned char *)"[ ]", 3); pop_html_element(html_context); put_chrs(html_context, (unsigned char *)" ", 1); html_context->special_f(html_context, SP_CONTROL, fc); }
static void html_img_do(unsigned char *a, unsigned char *object_src, struct html_context *html_context) { int ismap, usemap = 0; int add_brackets = 0; unsigned char *src = NULL; unsigned char *label = NULL; unsigned char *usemap_attr; struct document_options *options = html_context->options; int display_style = options->image_link.display_style; /* Note about display_style: * 0 means always display IMG * 1 means always display filename * 2 means display alt/title attribute if possible, IMG if not * 3 means display alt/title attribute if possible, filename if not */ usemap_attr = get_attr_val(a, (unsigned char *)"usemap", html_context->doc_cp); if (usemap_attr) { unsigned char *joined_urls = join_urls(html_context->base_href, usemap_attr); unsigned char *map_url; mem_free(usemap_attr); if (!joined_urls) return; map_url = straconcat((unsigned char *)"MAP@", joined_urls, (unsigned char *) NULL); mem_free(joined_urls); if (!map_url) return; html_stack_dup(html_context, ELEMENT_KILLABLE); mem_free_set(&format.link, map_url); format.form = NULL; format.style.attr |= AT_BOLD; usemap = 1; } ismap = format.link && has_attr(a, (unsigned char *)"ismap", html_context->doc_cp) && !usemap; if (display_style == 2 || display_style == 3) { label = get_attr_val(a, (unsigned char *)"alt", html_context->doc_cp); if (!label) label = get_attr_val(a, (unsigned char *)"title", html_context->doc_cp); /* Little hack to preserve rendering of [ ], in directory listings, * but we still want to drop extra spaces in alt or title attribute * to limit display width on certain websites. --Zas */ if (label && strlen((const char *)label) > 5) clr_spaces(label); } src = null_or_stracpy(object_src); if (!src) src = get_url_val(a, (unsigned char *)"src", html_context->doc_cp); if (!src) src = get_url_val(a, (unsigned char *)"dynsrc", html_context->doc_cp); /* If we have no label yet (no title or alt), so * just use default ones, or image filename. */ if (!label || !*label) { mem_free_set(&label, NULL); /* Do we want to display images with no alt/title and with no * link on them ? * If not, just exit now. */ if (!options->images && !format.link) { mem_free_if(src); if (usemap) pop_html_element(html_context); return; } add_brackets = 1; if (usemap) { label = stracpy((const unsigned char *)"USEMAP"); } else if (ismap) { label = stracpy((const unsigned char *)"ISMAP"); } else { if (display_style == 3) label = get_image_filename_from_src(options->image_link.filename_maxlen, src); } } else { label = get_image_label(options->image_link.label_maxlen, label); } if (!label || !*label) { mem_free_set(&label, NULL); add_brackets = 1; if (display_style == 1) label = get_image_filename_from_src(options->image_link.filename_maxlen, src); if (!label || !*label) mem_free_set(&label, stracpy((const unsigned char *)"IMG")); } mem_free_set(&format.image, NULL); mem_free_set(&format.title, NULL); if (label) { int img_link_tag = options->image_link.tagging; if (img_link_tag && (img_link_tag == 2 || add_brackets)) { unsigned char *img_link_prefix = options->image_link.prefix; unsigned char *img_link_suffix = options->image_link.suffix; unsigned char *new_label = straconcat(img_link_prefix, label, img_link_suffix, (unsigned char *) NULL); if (new_label) mem_free_set(&label, new_label); } if (!options->image_link.show_any_as_links) { put_image_label(a, label, html_context); } else { if (src) { format.image = join_urls(html_context->base_href, src); } format.title = get_attr_val(a, (unsigned char *)"title", html_context->doc_cp); if (ismap) { unsigned char *new_link; html_stack_dup(html_context, ELEMENT_KILLABLE); new_link = straconcat(format.link, (unsigned char *)"?0,0", (unsigned char *) NULL); if (new_link) mem_free_set(&format.link, new_link); } put_image_label(a, label, html_context); if (ismap) pop_html_element(html_context); mem_free_set(&format.image, NULL); mem_free_set(&format.title, NULL); } mem_free(label); } mem_free_if(src); if (usemap) pop_html_element(html_context); }
void ses_goto(struct session *ses, struct uri *uri, unsigned char *target_frame, struct location *target_location, enum cache_mode cache_mode, enum task_type task_type, int redir) { /* [gettext_accelerator_context(ses_goto)] */ struct task *task; int referrer_incomplete = 0; int malicious_uri = 0; int confirm_submit = uri->form && get_opt_bool("document.browse.forms" ".confirm_submit", ses); unsigned char *m1 = NULL, *message = NULL; struct memory_list *mlist = NULL; if (ses->doc_view && ses->doc_view->document && ses->doc_view->document->refresh) { kill_document_refresh(ses->doc_view->document->refresh); } assertm(!ses->loading_uri, "Buggy URI reference counting"); /* Reset the redirect counter if this is not a redirect. */ if (!redir) { ses->redirect_cnt = 0; } /* Figure out whether to confirm submit or not */ /* Only confirm submit if we are posting form data or a misleading URI * was detected. */ /* Note uri->post might be empty here but we are still supposely * posting form data so this should be more correct. */ if (uri->user && uri->userlen && get_opt_bool("document.browse.links.warn_malicious", ses) && check_malicious_uri(uri)) { malicious_uri = 1; confirm_submit = 1; } else if (uri->form) { /* First check if the referring URI was incomplete. It * indicates that the posted form data might be incomplete too. * See bug 460. */ if (ses->referrer) { struct cache_entry *cached; cached = find_in_cache(ses->referrer); referrer_incomplete = (cached && cached->incomplete); } if (referrer_incomplete) { confirm_submit = 1; } else if (get_validated_cache_entry(uri, cache_mode)) { confirm_submit = 0; } } if (!confirm_submit) { ses_load(ses, get_uri_reference(uri), target_frame, target_location, cache_mode, task_type); return; } task = mem_alloc(sizeof(*task)); if (!task) return; task->ses = ses; task->uri = get_uri_reference(uri); task->cache_mode = cache_mode; task->session_task.type = task_type; task->session_task.target.frame = null_or_stracpy(target_frame); task->session_task.target.location = target_location; if (malicious_uri) { unsigned char *host = memacpy(uri->host, uri->hostlen); unsigned char *user = memacpy(uri->user, uri->userlen); unsigned char *uristring = get_uri_string(uri, URI_PUBLIC); message = msg_text(ses->tab->term, N_("The URL you are about to follow might be maliciously " "crafted in order to confuse you. By following the URL " "you will be connecting to host \"%s\" as user \"%s\".\n\n" "Do you want to go to URL %s?"), host, user, uristring); mem_free_if(host); mem_free_if(user); mem_free_if(uristring); } else if (redir) { m1 = N_("Do you want to follow the redirect and post form data " "to URL %s?"); } else if (referrer_incomplete) { m1 = N_("The form data you are about to post might be incomplete.\n" "Do you want to post to URL %s?"); } else if (task_type == TASK_FORWARD) { m1 = N_("Do you want to post form data to URL %s?"); } else { m1 = N_("Do you want to repost form data to URL %s?"); } if (!message && m1) { unsigned char *uristring = get_uri_string(uri, URI_PUBLIC); message = msg_text(ses->tab->term, m1, uristring); mem_free_if(uristring); } add_to_ml(&mlist, task, (void *) NULL); if (task->session_task.target.frame) add_to_ml(&mlist, task->session_task.target.frame, (void *) NULL); msg_box(ses->tab->term, mlist, MSGBOX_FREE_TEXT, N_("Warning"), ALIGN_CENTER, message, task, 2, MSG_BOX_BUTTON(N_("~Yes"), post_yes, B_ENTER), MSG_BOX_BUTTON(N_("~No"), post_no, B_ESC)); }