示例#1
0
文件: header.c 项目: ezc/elinks
unsigned char *
parse_header(unsigned char *head, unsigned char *item, unsigned char **ptr)
{
	unsigned char *pos = head;

	if (!pos) return NULL;

	while (*pos) {
		unsigned char *end, *itempos, *value;
		int len;

		/* Go for a newline. */
		while (*pos && *pos != ASCII_LF) pos++;
		if (!*pos) break;
		pos++; /* Start of line now. */

		/* Does item match header line ? */
		for (itempos = item; *itempos && *pos; itempos++, pos++)
			if (c_toupper(*itempos) != c_toupper(*pos))
				break;

		if (!*pos) break; /* Nothing left to parse. */
		if (*itempos) continue; /* Do not match. */

		/* Be tolerant: we accept headers with
		 * weird syntax, since most browsers does it
		 * anyway, ie:
		 * name value
		 * name :value
		 * name = value
		 * name[TAB]:[TAB]value */

		end = pos;

		/* Skip leading whitespaces if any. */
		while (LWS(*pos)) pos++;
		if (!*pos) break; /* Nothing left to parse. */

		/* Eat ':' or '=' if any. */
		if (*pos == ':' || *pos == '=') pos++;
		if (!*pos) break; /* Nothing left to parse. */

		/* Skip whitespaces after separator if any. */
		while (LWS(*pos)) pos++;
		if (!*pos) break; /* Nothing left to parse. */

		if (pos == end) continue; /* Not an exact match (substring). */

		/* Find the end of line/string.
		 * We fail on control chars and DEL char. */
		end = pos;
		while (*end != ASCII_DEL && (*end > ' ' || LWS(*end))) end++;
		if (!*end) break; /* No end of line, nothing left to parse. */

		/* Ignore line if we encountered an unexpected char. */
		if (*end != ASCII_CR && *end != ASCII_LF) continue;

		/* Strip trailing whitespaces. */
		while (end > pos && LWS(end[-1])) end--;

		len = end - pos;
		assert(len >= 0);
		if_assert_failed break;

		if (!len) continue;	/* Empty value. */

		value = memacpy(pos, len);
		if (!value) break; /* Allocation failure, stop here. */

		if (ptr) *ptr = pos;
		return value;
	}

	return NULL;
}
示例#2
0
文件: header.c 项目: rkd77/elinks-tv
/* 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;
}