Пример #1
0
void
location_goto(struct document_view *doc_view, unsigned char *url)
{
	unsigned char *new_abs_url;
	struct uri *new_uri;
	struct delayed_goto *deg;

	/* Workaround for bug 611. Does not crash, but may lead to infinite loop.*/
	if (!doc_view) return;
	new_abs_url = join_urls(doc_view->document->uri,
	                        trim_chars(url, ' ', 0));
	if (!new_abs_url)
		return;
	new_uri = get_uri(new_abs_url, 0);
	mem_free(new_abs_url);
	if (!new_uri)
		return;
	deg = mem_calloc(1, sizeof(*deg));
	if (!deg) {
		done_uri(new_uri);
		return;
	}
	assert(doc_view->vs);
	deg->vs = doc_view->vs;
	deg->uri = new_uri;
	/* It does not seem to be very safe inside of frames to
	 * call goto_uri() right away. */
	register_bottom_half(delayed_goto, deg);
}
Пример #2
0
void
html_a(struct html_context *html_context, unsigned char *a,
       unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *href;

	href = get_url_val(a, (unsigned char *)"href", html_context->doc_cp);
	if (href) {
		unsigned char *target;

		mem_free_set(&format.link,
			     join_urls(html_context->base_href,
				       trim_chars(href, ' ', 0)));

		mem_free(href);

		target = get_target(html_context->options, a);
		if (target) {
			mem_free_set(&format.target, target);
		} else {
			mem_free_set(&format.target, stracpy(html_context->base_target));
		}

		if (0) {
			; /* Shut up compiler */
#ifdef CONFIG_GLOBHIST
		} else if (get_global_history_item(format.link)) {
			format.style.color.foreground = format.color.vlink;
			html_top->pseudo_class &= ~ELEMENT_LINK;
			html_top->pseudo_class |= ELEMENT_VISITED;
#endif
#ifdef CONFIG_BOOKMARKS
		} else if (get_bookmark(format.link)) {
			format.style.color.foreground = format.color.bookmark_link;
			html_top->pseudo_class &= ~ELEMENT_VISITED;
			/* XXX: Really set ELEMENT_LINK? --pasky */
			html_top->pseudo_class |= ELEMENT_LINK;
#endif
		} else {
			format.style.color.foreground = format.color.clink;
			html_top->pseudo_class &= ~ELEMENT_VISITED;
			html_top->pseudo_class |= ELEMENT_LINK;
		}

		mem_free_set(&format.title,
		             get_attr_val(a, (unsigned char *)"title", html_context->doc_cp));

		html_focusable(html_context, a);

	} else {
		pop_html_element(html_context);
	}

	set_fragment_identifier(html_context, a, (unsigned char *)"name");
}
Пример #3
0
void
html_frame(struct html_context *html_context, unsigned char *a,
           unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *name, *src, *url;

	src = get_url_val(a, (unsigned char *)"src", html_context->doc_cp);
	if (!src) {
		url = stracpy((const unsigned char *)"about:blank");
	} else {
		url = join_urls(html_context->base_href, src);
		mem_free(src);
	}
	if (!url) return;

	name = get_attr_val(a, (unsigned char *)"name", html_context->doc_cp);
	if (!name) {
		name = stracpy(url);
	} else if (!name[0]) {
		/* When name doesn't have a value */
		mem_free(name);
		name = stracpy(url);
	}
	if (!name) return;

	if (!html_context->options->frames || !html_top->frameset) {
		html_focusable(html_context, a);
		put_link_line((unsigned char *)"Frame: ", name, url, (unsigned char *)"", html_context);

	} else {
		if (html_context->special_f(html_context, SP_USED, NULL)) {
			html_context->special_f(html_context, SP_FRAME,
					       html_top->frameset, name, url);
		}
	}

	mem_free(name);
	mem_free(url);
}
Пример #4
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);
}
Пример #5
0
void end_dump(struct status *stat, void *p)
{
	struct cache_entry *ce = stat->ce;
	int oh = get_output_handle();
	if (oh == -1) return;
	if (ce && ce->redirect && dump_red_count++ < MAX_REDIRECTS) {
		unsigned char *u, *p;
		if (stat->state >= 0) change_connection(stat, NULL, PRI_CANCEL);
		u = join_urls(ce->url, ce->redirect);
		if (!http_bugs.bug_302_redirect) if (!ce->redirect_get && (p = strchr(ce->url, POST_CHAR))) add_to_strn(&u, p);
		load_url(u, stat, PRI_MAIN, 0);
		mem_free(u);
		return;
	}
	if (stat->state >= 0 && stat->state < S_TRANS) return;
	if (stat->state >= S_TRANS && dmp != D_SOURCE) return;
	if (dmp == D_SOURCE) {
		if (ce) {
			struct fragment *frag;
			nextfrag:
			foreach(frag, ce->frag) if (frag->offset <= dump_pos && frag->offset + frag->length > dump_pos) {
				int l = frag->length - (dump_pos - frag->offset);
				int w = hard_write(oh, frag->data + dump_pos - frag->offset, l);
				if (w != l) {
					detach_connection(stat, dump_pos);
					if (w < 0) fprintf(stderr, "Error writing to stdout: %s.\n", strerror(errno));
					else fprintf(stderr, "Can't write to stdout.\n");
					retval = RET_ERROR;
					goto terminate;
				}
				dump_pos += w;
				detach_connection(stat, dump_pos);
				goto nextfrag;
			}
		}
		if (stat->state >= 0) return;
	} else if (ce) {
Пример #6
0
/* prefix can have entities in it, but linkname cannot.  */
void
put_link_line(unsigned char *prefix, unsigned char *linkname,
	      unsigned char *link, unsigned char *target,
	      struct html_context *html_context)
{
	html_context->has_link_lines = 1;
	html_stack_dup(html_context, ELEMENT_KILLABLE);
	ln_break(html_context, 1);
	mem_free_set(&format.link, NULL);
	mem_free_set(&format.target, NULL);
	mem_free_set(&format.title, NULL);
	format.form = NULL;
	put_chrs(html_context, prefix, strlen((const char *)prefix));
	format.link = join_urls(html_context->base_href, link);
	format.target = stracpy(target);
	format.style.color.foreground = format.color.clink;
	/* linkname typically comes from get_attr_val, which
	 * has already expanded character entity references.
	 * Tell put_chrs not to expand them again.  */
	format.style.attr |= AT_NO_ENTITIES;
	put_chrs(html_context, linkname, strlen((const char *)linkname));
	ln_break(html_context, 1);
	pop_html_element(html_context);
}
Пример #7
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);
}
Пример #8
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);
}
Пример #9
0
static void
html_input_format(struct html_context *html_context, unsigned char *a,
	   	  struct form_control *fc)
{
	put_chrs(html_context, (unsigned char *)" ", 1);
	html_stack_dup(html_context, ELEMENT_KILLABLE);
	html_focusable(html_context, a);
	format.form = fc;
	if (format.title) mem_free(format.title);
	format.title = get_attr_val(a, (unsigned char *)"title", html_context->doc_cp);
	switch (fc->type) {
		case FC_TEXT:
		case FC_PASSWORD:
		case FC_FILE:
		{
			int i;

			format.style.attr |= AT_BOLD;
			for (i = 0; i < fc->size; i++)
				put_chrs(html_context, (unsigned char *)"_", 1);
			break;
		}
		case FC_CHECKBOX:
			format.style.attr |= AT_BOLD;
			put_chrs(html_context, (unsigned char *)"[&nbsp;]", 8);
			break;
		case FC_RADIO:
			format.style.attr |= AT_BOLD;
			put_chrs(html_context, (unsigned char *)"(&nbsp;)", 8);
			break;
		case FC_IMAGE:
		{
			unsigned char *al;

			mem_free_set(&format.image, NULL);
			al = get_url_val(a, (unsigned char *)"src", html_context->doc_cp);
			if (!al)
				al = get_url_val(a, (unsigned char *)"dynsrc",
				                 html_context->doc_cp);
			if (al) {
				format.image = join_urls(html_context->base_href, al);
				mem_free(al);
			}
			format.style.attr |= AT_BOLD;
			put_chrs(html_context, (unsigned char *)"[&nbsp;", 7);
			format.style.attr |= AT_NO_ENTITIES;
			if (fc->alt)
				put_chrs(html_context, fc->alt, strlen((const char *)fc->alt));
			else if (fc->name)
				put_chrs(html_context, fc->name, strlen((const char *)fc->name));
			else
				put_chrs(html_context, (unsigned char *)"Submit", 6);
			format.style.attr &= ~AT_NO_ENTITIES;

			put_chrs(html_context, (unsigned char *)"&nbsp;]", 7);
			break;
		}
		case FC_SUBMIT:
		case FC_RESET:
		case FC_BUTTON:
			format.style.attr |= AT_BOLD;
			put_chrs(html_context, (unsigned char *)"[&nbsp;", 7);
			if (fc->default_value) {
				format.style.attr |= AT_NO_ENTITIES;
				put_chrs(html_context, fc->default_value, strlen((const char *)fc->default_value));
				format.style.attr &= ~AT_NO_ENTITIES;
			}
			put_chrs(html_context, (unsigned char *)"&nbsp;]", 7);
			break;
		case FC_TEXTAREA:
		case FC_SELECT:
		case FC_HIDDEN:
			INTERNAL("bad control type");
	}
	pop_html_element(html_context);
	put_chrs(html_context, (unsigned char *)" ", 1);
}
Пример #10
0
void html_a( struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5 )
{
    int eax;
    int ecx;
    int edx;
    unsigned char *href;
    if ( get_attr_value( a, "href", html_context->doc_cp, HTML_ATTR_EAT_NL ) )
    {
        unsigned char *target;
        if ( html_context->stack.list_head_elinks )
        {
            mem_free( &html_context->stack.list_head_elinks );
        }
        strlen( &href[0] );
        if ( href[0] == ' ' )
        {
            do
            {
                href[0] = href[1];
                *(int*)(strlen( &href[0] ))--;
            }
            while ( href[0] == ' ' );
        }
        if ( eax )
        {
            if ( href[ eax - 1 ] == ' ' )
            {
                do
                {
                    *(char*)(edx - 1) = 0;
                    if ( eax == 1 )
                        href[0] = href[0];
                    else
                    }
                while ( *(char*)(edx - 2) != ' ' );
                href[0] = href[0];
            }
            eax += 0;
            memmove( &href[0], &href[0], 1 );
            &html_context->stack.list_head_elinks = ((void)( struct css_stylesheet *, struct uri *, unsigned char *, int  )*)join_urls( html_context->base_href, &href[0] );
            mem_free( &href[0] );
            if ( get_target( html_context->options, a ) )
            {
                if ( html_context->stack.list_head_elinks )
                {
                    mem_free( &html_context->stack.list_head_elinks );
                    html_context->stack.next = html_context->stack.next;
                }
                &html_context->stack.list_head_elinks = &target[0];
            }
            else
            {
                if ( html_context->stack.list_head_elinks )
                {
                    mem_free( &html_context->stack.list_head_elinks );
                }
                &html_context->stack.list_head_elinks = ((void)( struct css_stylesheet *, struct uri *, unsigned char *, int  )*)stracpy( html_context->base_target );
            }
            if ( get_global_history_item( &html_context->stack.list_head_elinks ) )
            {
                &html_context->stack.list_head_elinks = &html_context->stack.list_head_elinks;
                &html_context->stack.list_head_elinks &= -2;
                &html_context->stack.list_head_elinks |= 2;
            }
            else
            {
                &html_context->stack.list_head_elinks = html_context->stack.next ? &html_context->stack.list_head_elinks : &html_context->stack.list_head_elinks;
                &html_context->stack.list_head_elinks &= -3;
                &html_context->stack.list_head_elinks |= 1;
            }
            if ( html_context->stack.list_head_elinks )
            {
                mem_free( &html_context->stack.list_head_elinks );
            }
            &html_context->stack.list_head_elinks = ((void)( struct css_stylesheet *, struct uri *, unsigned char *, int  )*)get_attr_value( a, "title", html_context->doc_cp, HTML_ATTR_NONE );
            html_focusable( &html_context[0], a );
            xxx3 = "name";
            html_context = &html_context[0];
            a = a;
        }
        memmove( &href[0], &href[0], 1 );
        &html_context->stack.list_head_elinks = ((void)( struct css_stylesheet *, struct uri *, unsigned char *, int  )*)join_urls( html_context->base_href, &href[0] );
        mem_free( &href[0] );
    }
    else
Пример #11
0
void
html_script(struct html_context *html_context, unsigned char *a,
            unsigned char *html, unsigned char *eof, unsigned char **end)
{
#ifdef CONFIG_ECMASCRIPT
	/* TODO: <noscript> processing. Well, same considerations apply as to
	 * CSS property display: none processing. */
	/* TODO: Charsets for external scripts. */
	unsigned char *type, *language, *src;
	int in_comment = 0;
#endif

	html_skip(html_context, a);

#ifdef CONFIG_ECMASCRIPT
	/* We try to process nested <script> if we didn't process the parent
	 * one. That's why's all the fuzz. */
	/* Ref:
	 * http://www.ietf.org/internet-drafts/draft-hoehrmann-script-types-03.txt
	 */
	type = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp);
	if (type) {
		unsigned char *pos = type;

		if (!c_strncasecmp((const char *)type, "text/", 5)) {
			pos += 5;

		} else if (!c_strncasecmp((const char *)type, "application/", 12)) {
			pos += 12;

		} else {
			mem_free(type);
not_processed:
			/* Permit nested scripts and retreat. */
			html_top->invisible++;
			return;
		}

		if (!c_strncasecmp((const char *)pos, "javascript", 10)) {
			int len = strlen((const char *)pos);

			if (len > 10 && !isdigit(pos[10])) {
				mem_free(type);
				goto not_processed;
			}

		} else if (c_strcasecmp((const char *)pos, "ecmascript")
		    && c_strcasecmp((const char *)pos, "jscript")
		    && c_strcasecmp((const char *)pos, "livescript")
		    && c_strcasecmp((const char *)pos, "x-javascript")
		    && c_strcasecmp((const char *)pos, "x-ecmascript")) {
			mem_free(type);
			goto not_processed;
		}

		mem_free(type);
	}

	/* Check that the script content is ecmascript. The value of the
	 * language attribute can be JavaScript with optional version digits
	 * postfixed (like: ``JavaScript1.1'').
	 * That attribute is deprecated in favor of type by HTML 4.01 */
	language = get_attr_val(a, (unsigned char *)"language", html_context->doc_cp);
	if (language) {
		int languagelen = strlen((const char *)language);

		if (languagelen < 10
		    || (languagelen > 10 && !isdigit(language[10]))
		    || c_strncasecmp((const char *)language, "javascript", 10)) {
			mem_free(language);
			html_top->invisible++;
			return;
			//goto not_processed;
		}

		mem_free(language);
	}

	if (html_context->part->document
	    && (src = get_attr_val(a, (unsigned char *)"src", html_context->doc_cp))) {
		/* External reference. */

		unsigned char *import_url;
		struct uri *uri;

		if (!get_opt_bool((const unsigned char *)"ecmascript.enable", NULL)) {
			mem_free(src);
			html_top->invisible++;
			return;
			//goto not_processed;
		}

		/* HTML <head> urls should already be fine but we can.t detect them. */
		import_url = join_urls(html_context->base_href, src);
		mem_free(src);
		if (!import_url) goto imported;

		uri = get_uri(import_url, URI_BASE);
		if (!uri) goto imported;

		/* Request the imported script as part of the document ... */
		html_context->special_f(html_context, SP_SCRIPT, uri);
		done_uri(uri);

		/* Create URL reference onload snippet. */
		insert_in_string(&import_url, 0, (const unsigned char *)"^", 1);
		add_to_string_list(&html_context->part->document->onload_snippets,
		                   import_url, -1);

imported:
		/* Retreat. Do not permit nested scripts, tho'. */
		if (import_url) mem_free(import_url);
		return;
	}

	/* Positive, grab the rest and interpret it. */

	/* First position to the real script start. */
	while (html < eof && *html <= ' ') html++;
	if (eof - html > 4 && !strncmp((const char *)html, "<!--", 4)) {
		in_comment = 1;
		/* We either skip to the end of line or to -->. */
		for (; *html != '\n' && *html != '\r' && eof - html >= 3; html++) {
			if (!strncmp((const char *)html, "-->", 3)) {
				/* This means the document is probably broken.
				 * We will now try to process the rest of
				 * <script> contents, which is however likely
				 * to be empty. Should we try to process the
				 * comment too? Currently it seems safer but
				 * less tolerant to broken pages, if there are
				 * any like this. */
				html += 3;
				in_comment = 0;
				break;
			}
		}
	}

	*end = html;

	/* Now look ahead for the script end. The <script> contents is raw
	 * CDATA, so we just look for the ending tag and need not care for
	 * any quote marks counting etc - YET, we are more tolerant and permit
	 * </script> stuff inside of the script if the whole <script> element
	 * contents is wrapped in a comment. See i.e. Mozilla bug 26857 for fun
	 * reading regarding this. */
	for (; *end < eof; (*end)++) {
		unsigned char *name;
		int namelen;

		if (in_comment) {
			/* TODO: If we ever get some standards-quirk mode
			 * distinction, this should be disabled in the
			 * standards mode (and we should just look for CDATA
			 * end, which is "</"). --pasky */
			if (eof - *end >= 3 && !strncmp((const char *)*end, "-->", 3)) {
				/* Next iteration will jump passed the ending '>' */
				(*end) += 2;
				in_comment = 0;
			}
			continue;
			/* XXX: Scan for another comment? That's admittelly
			 * already stretching things a little bit to an
			 * extreme ;-). */
		}

		if (**end != '<')
			continue;
		/* We want to land before the closing element, that's why we
		 * don't pass @end also as the appropriate parse_element()
		 * argument. */
		if (parse_element(*end, eof, &name, &namelen, NULL, NULL))
			continue;
		if (c_strlcasecmp(name, namelen, (const unsigned char *)"/script", 7))
			continue;
		/* We have won! */
		break;
	}
	if (*end >= eof) {
		/* Either the document is not completely loaded yet or it's
		 * broken. At any rate, run away screaming. */
		*end = eof; /* Just for sanity. */
		return;
	}

	if (html_context->part->document && *html != '^') {
		add_to_string_list(&html_context->part->document->onload_snippets,
		                   html, *end - html);
	}
#endif
}