Example #1
0
File: auth.c Project: Efreak/elinks
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);
}
Example #2
0
/* @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;
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #5
0
/* 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);
}
Example #6
0
File: link.c Project: rkd77/felinks
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);
}
Example #7
0
File: smb2.c Project: Efreak/elinks
/** 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;
}
Example #8
0
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));
}
Example #9
0
/** 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;
}
Example #10
0
File: kbd.c Project: Efreak/elinks
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);
}
Example #11
0
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);
}
Example #12
0
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;
	}
}
Example #13
0
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);
}
Example #14
0
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;
	}
}
Example #15
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));
}
Example #16
0
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);
}
Example #17
0
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
    }
}
Example #18
0
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);
}
Example #19
0
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;
	}
}
Example #20
0
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);
}
Example #21
0
/* 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;
}
Example #22
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;
}
Example #23
0
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);
}
Example #24
0
File: smb2.c Project: Efreak/elinks
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);
	}
}
Example #25
0
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));
}
Example #26
0
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);
}
Example #27
0
/** 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;
}
Example #28
0
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);
}
Example #29
0
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);
}
Example #30
0
File: task.c Project: ezc/elinks
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));
}