Example #1
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, "method", html_context->doc_cp);
	if (al) {
		if (!c_strcasecmp(al, "post")) {
			unsigned char *enctype;

			enctype  = get_attr_val(a, "enctype",
						html_context->doc_cp);

			form->method = FORM_METHOD_POST;
			if (enctype) {
				if (!c_strcasecmp(enctype, "multipart/form-data"))
					form->method = FORM_METHOD_POST_MP;
				else if (!c_strcasecmp(enctype, "text/plain"))
					form->method = FORM_METHOD_POST_TEXT_PLAIN;
				mem_free(enctype);
			}
		}
		mem_free(al);
	}
	form->onsubmit = get_attr_val(a, "onsubmit", html_context->doc_cp);
	al = get_attr_val(a, "name", html_context->doc_cp);
	if (al) form->name = al;

	al = get_attr_val(a, "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(form->action, POST_CHAR));

		/* GET method URIs should not have '?'. */
		assert(!form->action
			|| form->method != FORM_METHOD_GET
			|| !strchr(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 #2
0
File: mime.c Project: Efreak/elinks
unsigned char *
get_content_type(struct cache_entry *cached)
{
	unsigned char *extension, *ctype;

	debug_get_content_type_params(cached);

	if (cached->content_type)
		return cached->content_type;

	/* If there's one in header, it's simple.. */
	if (cached->head) {
		ctype = get_cache_header_content_type(cached);
		if (ctype && *ctype) {
			cached->content_type = ctype;
			return ctype;
		}
		mem_free_if(ctype);
	}

	/* We can't use the extension string we are getting below, because we
	 * want to support also things like "ps.gz" - that'd never work, as we
	 * would always compare only to "gz". */
	/* Guess type accordingly to the extension */
	extension = get_extension_from_uri(cached->uri);
	debug_extension(extension);

	if (extension) {
		/* XXX:	A little hack for making extension handling case
		 * insensitive. We could probably do it better by making
		 * guess_encoding() case independent the real problem however
		 * is with default (via option system) and mimetypes resolving
		 * doing that option and hash lookup will not be easy to
		 * convert. --jonas */
		convert_to_lowercase_locale_indep(extension, strlen(extension));

		ctype = get_extension_content_type(extension);
		mem_free(extension);
		if (ctype && *ctype) {
			cached->content_type = ctype;
			return ctype;
		}
		mem_free_if(ctype);
	}

	ctype = get_fragment_content_type(cached);
	if (ctype && *ctype) {
		cached->content_type = ctype;
		return ctype;
	}

	debug_ctype(get_default_mime_type());

	/* text/plain for pager mode */
	if (cached->uri && cached->uri->string
	    && !strcmp(cached->uri->string, "file:///dev/stdin")) {
		cached->content_type = stracpy("text/plain");
	} else
		/* Fallback.. use some hardwired default */
		cached->content_type = stracpy(get_default_mime_type());

	return cached->content_type;
}
Example #3
0
void
html_input(struct html_context *html_context, unsigned char *a,
           unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al;
	struct form_control *fc;
	int cp = html_context->doc_cp;

	fc = init_form_control(FC_TEXT, a, html_context);
	if (!fc) return;

	al = get_attr_val(a, "type", cp);
	if (al) {
		if (!c_strcasecmp(al, "text")) fc->type = FC_TEXT;
		else if (!c_strcasecmp(al, "hidden")) fc->type = FC_HIDDEN;
		else if (!c_strcasecmp(al, "button")) fc->type = FC_BUTTON;
		else if (!c_strcasecmp(al, "checkbox")) fc->type = FC_CHECKBOX;
		else if (!c_strcasecmp(al, "radio")) fc->type = FC_RADIO;
		else if (!c_strcasecmp(al, "password")) fc->type = FC_PASSWORD;
		else if (!c_strcasecmp(al, "submit")) fc->type = FC_SUBMIT;
		else if (!c_strcasecmp(al, "reset")) fc->type = FC_RESET;
		else if (!c_strcasecmp(al, "file")) fc->type = FC_FILE;
		else if (!c_strcasecmp(al, "image")) fc->type = FC_IMAGE;
		/* else unknown type, let it default to FC_TEXT. */
		mem_free(al);
	}

	if (fc->type == FC_HIDDEN)
		fc->default_value = get_lit_attr_val(a, "value", cp);
	else if (fc->type != FC_FILE)
		fc->default_value = get_attr_val(a, "value", cp);
	if (!fc->default_value) {
		if (fc->type == FC_CHECKBOX)
			fc->default_value = stracpy("on");
		else if (fc->type == FC_SUBMIT)
			fc->default_value = stracpy("Submit");
		else if (fc->type == FC_RESET)
			fc->default_value = stracpy("Reset");
		else if (fc->type == FC_BUTTON)
			fc->default_value = stracpy("Button");
	}
	if (!fc->default_value)
		fc->default_value = stracpy("");

	fc->id = get_attr_val(a, "id", cp);
	fc->name = get_attr_val(a, "name", cp);

	fc->size = get_num(a, "size", cp);
	if (fc->size == -1)
		fc->size = html_context->options->default_form_input_size;
	fc->size++;
	if (fc->size > html_context->options->box.width)
		fc->size = html_context->options->box.width;
	fc->maxlength = get_num(a, "maxlength", cp);
	if (fc->maxlength == -1) fc->maxlength = INT_MAX;
	if (fc->type == FC_CHECKBOX || fc->type == FC_RADIO)
		fc->default_state = has_attr(a, "checked", cp);
	if (fc->type == FC_IMAGE)
		fc->alt = get_attr_val(a, "alt", cp);

	if (fc->type != FC_HIDDEN) {
		html_input_format(html_context, a, fc);
	}

	html_context->special_f(html_context, SP_CONTROL, fc);
}
Example #4
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 = 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, "SELECT", 6)) {
		add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);
		goto end_parse;
	}

	if (!c_strlcasecmp(name, namelen, "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, "disabled", html_context->doc_cp))
				goto see;
			if (preselect == -1
			    && has_attr(t_attr, "selected", html_context->doc_cp))
				preselect = order;
			value = get_attr_val(t_attr, "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, "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, "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, "label", html_context->doc_cp);

			if (!label) {
				label = stracpy("");
				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 = 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, "id", html_context->doc_cp);
	fc->name = get_attr_val(attr, "name", html_context->doc_cp);
	fc->default_state = preselect < 0 ? 0 : preselect;
	fc->default_value = order ? stracpy(values[fc->default_state]) : stracpy("");
	fc->nvalues = order;
	fc->values = values;
	fc->menu = detach_menu(&lnk_menu);
	fc->labels = labels;

	menu_labels(fc->menu, "", labels);
	put_chrs(html_context, "[", 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(labels[i]));
	}

	for (i = 0; i < max_width; i++)
		put_chrs(html_context, "_", 1);

	pop_html_element(html_context);
	put_chrs(html_context, "]", 1);
	html_context->special_f(html_context, SP_CONTROL, fc);
}
Example #5
0
void g_put_chars(struct g_part *p, unsigned char *s, int l)
{
	struct g_object_text *t = NULL;
	struct link *link;
	if (putchars_link_ptr) {
		link = NULL;
		goto check_link;
	}
	while (par_format.align != AL_NO && p->cx == -1 && l && *s == ' ') s++, l--;
	if (!l) return;
	g_nobreak = 0;
	if (p->cx < par_format.leftmargin * G_HTML_MARGIN) p->cx = par_format.leftmargin * G_HTML_MARGIN;
	if (html_format_changed) {
		if (memcmp(&ta_cache, &format, sizeof(struct text_attrib_beginning)) || xstrcmp(cached_font_face, format.fontface) || cached_font_face == to_je_ale_prasarna ||
	xstrcmp(format.link, last_link) || xstrcmp(format.target, last_target) ||
	    xstrcmp(format.image, last_image) || format.form != last_form
	    || ((format.js_event || last_js_event) && compare_js_event_spec(format.js_event, last_js_event))	) {
			/*if (!html_format_changed) internal("html_format_changed not set");*/
			flush_pending_text_to_line(p);
			if (xstrcmp(cached_font_face, format.fontface) || cached_font_face == to_je_ale_prasarna) {
				if (cached_font_face && cached_font_face != to_je_ale_prasarna) mem_free(cached_font_face);
				cached_font_face = stracpy(format.fontface);
			}
			memcpy(&ta_cache, &format, sizeof(struct text_attrib_beginning));
			if (p->current_style) g_free_style(p->current_style);
			p->current_style = get_style_by_ta(&format);
		}
		html_format_changed = 0;
	}
	/*if (p->cx <= par_format.leftmargin * G_HTML_MARGIN && *s == ' ' && par_format.align != AL_NO) s++, l--;*/
	if (!p->text) {
		link = NULL;
		t = mem_calloc(sizeof(struct g_object_text) + ALLOC_GR);
		t->mouse_event = g_text_mouse;
		t->draw = g_text_draw;
		t->destruct = g_text_destruct;
		t->get_list = NULL;
		/*t->style = get_style_by_ta(format);*/
		t->style = g_clone_style(p->current_style);
		t->bg = NULL; /* FIXME!!! */
		t->yw = t->style->height;
		/*t->xw = 0;
		t->y = 0;*/
		if (format.baseline) {
			if (format.baseline < 0) t->y = -(t->style->height / 3);
			if (format.baseline > 0) t->y = get_real_font_size(format.baseline) - (t->style->height / 2);
		}
		check_link:
		if (last_link || last_image || last_form || format.link || format.image || format.form 
		|| format.js_event || last_js_event
		) goto process_link;
		back_link:
		if (putchars_link_ptr) {
			*putchars_link_ptr = link;
			return;
		}

		if (!link) t->link_num = -1;
		else {
			t->link_num = link - p->data->links;
			t->link_order = link->obj_order++;
		}

		t->text[0] = 0;
		p->pending_text_len = 0;
		p->text = t;
	}
	if (p->pending_text_len == -1) {
		p->pending_text_len = strlen(p->text->text);
		goto a1;
	}
	if ((p->pending_text_len & ~(ALLOC_GR - 1)) != ((p->pending_text_len + l) & ~(ALLOC_GR - 1))) a1:{
		struct g_object_text *t;
		if ((unsigned)l > MAXINT) overalloc();
		if ((unsigned)p->pending_text_len + (unsigned)l > MAXINT - ALLOC_GR) overalloc();
		t = mem_realloc(p->text, sizeof(struct g_object_text) + ((p->pending_text_len + l + ALLOC_GR) & ~(ALLOC_GR - 1)));
		if (p->w.last_wrap >= p->text->text && p->w.last_wrap < p->text->text + p->pending_text_len) p->w.last_wrap += (unsigned char *)t - (unsigned char *)p->text;
		if (p->w.last_wrap_obj == p->text) p->w.last_wrap_obj = t;
		p->text = t;
	}
	memcpy(p->text->text + p->pending_text_len, s, l), p->text->text[p->pending_text_len += l] = 0;
	p->text->xw += g_text_width(p->text->style, p->text->text + p->pending_text_len - l); /* !!! FIXME: move to g_wrap_text */
	if (par_format.align != AL_NO) {
		p->w.text = p->text->text + p->pending_text_len - l;
		p->w.style = p->text->style;
		p->w.obj = p->text;
		p->w.width = rm(par_format) - par_format.leftmargin * G_HTML_MARGIN;
		if (p->w.width < 0) p->w.width = 0;
		if (!g_wrap_text(&p->w)) {
			split_line_object(p, p->w.last_wrap_obj, p->w.last_wrap);
		}
	}
	return;

	/* !!! WARNING: THE FOLLOWING CODE IS SHADOWED IN HTML_R.C */

	process_link:
	if ((last_link /*|| last_target*/ || last_image || last_form) &&
	    !putchars_link_ptr &&
	    !xstrcmp(format.link, last_link) && !xstrcmp(format.target, last_target) &&
	    !xstrcmp(format.image, last_image) && format.form == last_form
	    && ((!format.js_event && !last_js_event) || !compare_js_event_spec(format.js_event, last_js_event))) {
		if (!p->data) goto back_link;
		if (!p->data->nlinks) {
			internal("no link");
			goto back_link;
		}
		link = &p->data->links[p->data->nlinks - 1];
		goto back_link;
	} else {
		if (last_link) mem_free(last_link);
		if (last_target) mem_free(last_target);
		if (last_image) mem_free(last_image);
		free_js_event_spec(last_js_event);
		last_link = last_target = last_image = NULL;
		last_form = NULL;
		last_js_event = NULL;
		if (!(format.link || format.image || format.form || format.js_event)) goto back_link;
		/*if (d_opt->num_links) {
			unsigned char s[64];
			unsigned char *fl = format.link, *ft = format.target, *fi = format.image;
			struct form_control *ff = format.form;
			struct js_event_spec *js = format.js_event;
			format.link = format.target = format.image = NULL;
			format.form = NULL;
			format.js_event = NULL;
			s[0] = '[';
			snzprint(s + 1, 62, p->link_num);
			strcat(s, "]");
			g_put_chars(p, s, strlen(s));
			if (ff && ff->type == FC_TEXTAREA) g_line_break(p);
			if (p->cx < par_format.leftmargin * G_HTML_MARGIN) p->cx = par_format.leftmargin * G_HTML_MARGIN;
			format.link = fl, format.target = ft, format.image = fi;
			format.form = ff;
			format.js_event = js;
		}*/
		p->link_num++;
		last_link = stracpy(format.link);
		last_target = stracpy(format.target);
		last_image = stracpy(format.image);
		last_form = format.form;
		copy_js_event_spec(&last_js_event, format.js_event);
		if (!p->data) goto back_link;
		if (!(link = new_link(p->data))) goto back_link;
		link->num = p->link_num - 1;
		link->pos = DUMMY;
		copy_js_event_spec(&link->js_event, format.js_event);
		if (!last_form) {
			link->type = L_LINK;
			link->where = stracpy(last_link);
			link->target = stracpy(last_target);
		} else {
			link->type = last_form->type == FC_TEXT || last_form->type == FC_PASSWORD || last_form->type == FC_FILE ? L_FIELD : last_form->type == FC_TEXTAREA ? L_AREA : last_form->type == FC_CHECKBOX || last_form->type == FC_RADIO ? L_CHECKBOX : last_form->type == FC_SELECT ? L_SELECT : L_BUTTON;
			link->form = last_form;
			link->target = stracpy(last_form->target);
		}
		link->where_img = stracpy(last_image);
		link->sel_color = 0;
		link->n = 0;
	}
	goto back_link;
}
Example #6
0
void do_image(struct g_part *p, struct image_description *im)
{
	struct g_object_image *io;
	struct link *link;
	link = NULL;
	putchars_link_ptr = &link;
	g_put_chars(p, NULL, 0);
	putchars_link_ptr = NULL;
	if (!link) im->link_num = -1;
	else {
		im->link_num = link - p->data->links;
		im->link_order = link->obj_order++;
		if (link->img_alt) mem_free(link->img_alt);
		link->img_alt = stracpy(im->alt);
	}
	io = insert_image(p, im);
	if (!io) goto ab;
	io->ismap = im->ismap;
	add_object(p, (struct g_object *)io);
	if (im->usemap && p->data) {
		unsigned char *tag = extract_position(im->usemap);
		struct additional_file *af = request_additional_file(current_f_data, im->usemap);
		af->need_reparse = 1;
		if (af->rq && (af->rq->state == O_LOADING || af->rq->state == O_INCOMPLETE || af->rq->state == O_OK) && af->rq->ce) {
			struct memory_list *ml;
			struct menu_item *menu;
			struct cache_entry *ce = af->rq->ce;
			unsigned char *start, *end;
			int i;
			struct image_map *map;
			get_file(af->rq, &start, &end);
			if (start == end) goto ft;
			if (get_image_map(ce->head, start, end, tag, &menu, &ml, format.href_base, format.target_base, 0, 0, 0, 1)) goto ft;
			map = mem_alloc(sizeof(struct image_map));
			map->n_areas = 0;
			for (i = 0; menu[i].text; i++) {
				struct link_def *ld = menu[i].data;
				struct map_area *a;
				struct link *link;
				int shape = !ld->shape || !*ld->shape ? SHAPE_RECT : !strcasecmp(ld->shape, "default") ? SHAPE_DEFAULT : !strcasecmp(ld->shape, "rect") ? SHAPE_RECT : !strcasecmp(ld->shape, "circle") ? SHAPE_CIRCLE : !strcasecmp(ld->shape, "poly") || !strcasecmp(ld->shape, "polygon") ? SHAPE_POLY : -1;
				if (shape == -1) continue;
				if ((unsigned)map->n_areas > (MAXINT - sizeof(struct image_map)) / sizeof(struct map_area) - 1) overalloc();
				map = mem_realloc(map, sizeof(struct image_map) + (map->n_areas + 1) * sizeof(struct map_area));
				a = &map->area[map->n_areas++];
				a->shape = shape;
				a->coords = DUMMY;
				a->ncoords = 0;
				if (ld->coords) {
					unsigned char *p = ld->coords;
					int num;
					next_coord:
					num = 0;
					while (*p && (*p < '0' || *p > '9')) p++;
					if (!*p) goto noc;
					while (*p >= '0' && *p <= '9' && num < 10000000) num = num * 10 + *p - '0', p++;
					if (*p == '.') {
						p++;
						while (*p >= '0' && *p <= '9') p++;
					}
					if (*p == '%' && num < 1000) {
						int m = io->xw < io->yw ? io->xw : io->yw;
						num = num * m / 100;
						p++;
					} else num = num * d_opt->image_scale / 100;
					if ((unsigned)a->ncoords > MAXINT / sizeof(int) - 1) overalloc();
					a->coords = mem_realloc(a->coords, (a->ncoords + 1) * sizeof(int));
					a->coords[a->ncoords++] = num;
					goto next_coord;
				}
				noc:
				if (!(link = new_link(p->data))) a->link_num = -1;
				else {
					link->pos = DUMMY;
					link->type = L_LINK;
					link->where = stracpy(ld->link);
					link->target = stracpy(ld->target);
					link->img_alt = stracpy(ld->label);
					link->where_img = stracpy(im->url);
#ifdef JS
					if (ld->onclick || ld->ondblclick || ld->onmousedown || ld->onmouseup || ld->onmouseover || ld->onmouseout || ld->onmousemove) {
						create_js_event_spec(&link->js_event);
						link->js_event->click_code = stracpy(ld->onclick);
						link->js_event->dbl_code = stracpy(ld->ondblclick);
						link->js_event->down_code = stracpy(ld->onmousedown);
						link->js_event->up_code = stracpy(ld->onmouseup);
						link->js_event->over_code = stracpy(ld->onmouseover);
						link->js_event->out_code = stracpy(ld->onmouseout);
						link->js_event->move_code = stracpy(ld->onmousemove);
					}
#endif
					a->link_num = link - p->data->links;
				}
				if (last_link) mem_free(last_link), last_link = NULL;
			}
			io->map = map;
			freeml(ml);
			ft:;
		}
		if (tag) mem_free(tag);
	}
	ab:
	if (im->usemap) mem_free(im->usemap);
}
Example #7
0
void
html_frameset(struct html_context *html_context, unsigned char *a,
              unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	struct frameset_param fp;
	unsigned char *cols, *rows;
	int width, height;

	/* XXX: This is still not 100% correct. We should also ignore the
	 * frameset when we encountered anything 3v1l (read as: non-whitespace
	 * text/element/anything) in the document outside of <head>. Well, this
	 * is still better than nothing and it should heal up the security
	 * concerns at least because sane sites should enclose the documents in
	 * <body> elements ;-). See also bug 171. --pasky */
	if (search_html_stack(html_context, (unsigned char *)"BODY")
	    || !html_context->options->frames
	    || !html_context->special_f(html_context, SP_USED, NULL))
		return;

	cols = get_attr_val(a, (unsigned char *)"cols", html_context->doc_cp);
	if (!cols) {
		cols = stracpy((const unsigned char *)"100%");
		if (!cols) return;
	}

	rows = get_attr_val(a, (unsigned char *)"rows", html_context->doc_cp);
	if (!rows) {
		rows = stracpy((const unsigned char *)"100%");
	       	if (!rows) {
			mem_free(cols);
			return;
		}
	}

	if (!html_top->frameset) {
		width = html_context->options->box.width;
		height = html_context->options->box.height;
		html_context->options->needs_height = 1;
	} else {
		struct frameset_desc *frameset_desc = html_top->frameset;
		int offset;

		if (frameset_desc->box.y >= frameset_desc->box.height)
			goto free_and_return;
		offset = frameset_desc->box.x
			 + frameset_desc->box.y * frameset_desc->box.width;
		width = frameset_desc->frame_desc[offset].width;
		height = frameset_desc->frame_desc[offset].height;
	}

	fp.width = fp.height = NULL;

	parse_frame_widths(cols, width, HTML_FRAME_CHAR_WIDTH,
			   &fp.width, &fp.x);
	parse_frame_widths(rows, height, HTML_FRAME_CHAR_HEIGHT,
			   &fp.height, &fp.y);

	fp.parent = html_top->frameset;
	if (fp.x && fp.y) {
		html_top->frameset = (struct frameset_desc *)html_context->special_f(html_context, SP_FRAMESET, &fp);
	}
	mem_free_if(fp.width);
	mem_free_if(fp.height);

free_and_return:
	mem_free(cols);
	mem_free(rows);
}
Example #8
0
File: link.c Project: rkd77/felinks
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, "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("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, "ismap", html_context->doc_cp)
	        && !usemap;

	if (display_style == 2 || display_style == 3) {
		label = get_attr_val(a, "alt", html_context->doc_cp);
		if (!label)
			label = get_attr_val(a, "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(label) > 5) clr_spaces(label);
	}

	src = null_or_stracpy(object_src);
	if (!src) src = get_url_val(a, "src", html_context->doc_cp);
	if (!src) src = get_url_val(a, "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("USEMAP");
		} else if (ismap) {
			label = stracpy("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("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, "title", html_context->doc_cp);

			if (ismap) {
				unsigned char *new_link;

				html_stack_dup(html_context, ELEMENT_KILLABLE);
				new_link = straconcat(format.link, "?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 #9
0
/* Extract the value of name part of the value of attribute content.
 * Ie. @name = "charset" and @str = "text/html; charset=iso-8859-1"
 * will store in *@ret an allocated string containing "iso-8859-1".
 * It supposes that separator is ';' and ignore first element in the
 * list. (ie. '1' is ignored in "1; URL=xxx")
 * The return value is one of:
 *
 * - HEADER_PARAM_FOUND: the parameter was found, copied, and stored in *@ret.
 * - HEADER_PARAM_NOT_FOUND: the parameter is not there.  *@ret is now NULL.
 * - HEADER_PARAM_OUT_OF_MEMORY: error. *@ret is now NULL.
 *
 * If @ret is NULL, then this function doesn't actually access *@ret,
 * and cannot fail with HEADER_PARAM_OUT_OF_MEMORY.  Some callers may
 * rely on this. */
enum parse_header_param
parse_header_param(unsigned char *str, unsigned char *name, unsigned char **ret)
{
	unsigned char *p = str;
	int namelen, plen = 0;

	if (ret) *ret = NULL;	/* default in case of early return */

	assert(str && name && *name);
	if_assert_failed return HEADER_PARAM_NOT_FOUND;

	/* Returns now if string @str is empty. */
	if (!*p) return HEADER_PARAM_NOT_FOUND;

	namelen = strlen((const char *)name);
	do {
		p = (unsigned char *)strchr((char *)p, ';');
		if (!p) return HEADER_PARAM_NOT_FOUND;

		while (*p && (*p == ';' || *p <= ' ')) p++;
		if (strlen((const char *)p) < namelen) return HEADER_PARAM_NOT_FOUND;
	} while (c_strncasecmp((const char *)p, (const char *)name, namelen));

	p += namelen;

	while (*p && (*p <= ' ' || *p == '=')) p++;
	if (!*p) {
		if (ret) {
			*ret = stracpy((const unsigned char *)"");
			if (!*ret)
				return HEADER_PARAM_OUT_OF_MEMORY;
		}
		return HEADER_PARAM_FOUND;
	}

	while ((p[plen] > ' ' || LWS(p[plen])) && p[plen] != ';') plen++;

	/* Trim ending spaces */
	while (plen > 0 && LWS(p[plen - 1])) plen--;

	/* XXX: Drop enclosing single quotes if there's some.
	 *
	 * Some websites like newsnow.co.uk are using single quotes around url
	 * in URL field in meta tag content attribute like this:
	 * <meta http-equiv="Refresh" content="0; URL='http://www.site.com/path/xxx.htm'">
	 *
	 * This is an attempt to handle that, but it may break something else.
	 * We drop all pair of enclosing quotes found (eg. '''url''' => url).
	 * Please report any issue related to this. --Zas */
	while (plen > 1 && *p == '\'' && p[plen - 1] == '\'') {
		p++;
		plen -= 2;
	}

	if (ret) {
		*ret = memacpy(p, plen);
		if (!*ret)
			return HEADER_PARAM_OUT_OF_MEMORY;
	}
	return HEADER_PARAM_FOUND;
}