Exemplo n.º 1
0
css_error node_has_attribute_prefix(void *pw, void *n,
		const css_qname *qname,
		lwc_string *value,
		bool *match)
{
	node *node = n;
	uint32_t i;
	UNUSED(pw);

	*match = false;
	
	for (i = 0; i < node->n_attrs; i++) {
		assert(lwc_string_caseless_isequal(
				node->attrs[i].name, qname->name, match) == 
				lwc_error_ok);
		if (*match == true)
			break;
	}
	
	if (*match == true) {
		size_t len = lwc_string_length(node->attrs[i].value);
		const char *data = lwc_string_data(node->attrs[i].value);

		size_t vlen = lwc_string_length(value);
		const char *vdata = lwc_string_data(value);

		if (len < vlen)
			*match = false;
		else
			*match = (strncasecmp(data, vdata, vlen) == 0);
	}
	
	return CSS_OK;
}
Exemplo n.º 2
0
/**
 * Callback to determine if a node has an attribute with the given name whose
 * value contains the substring given.
 *
 * \param pw     HTML document
 * \param node   DOM node
 * \param qname  Name to match
 * \param value  Value to match
 * \param match  Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_NOMEM on memory exhaustion.
 *
 * \post \a match will contain true if the node matches and false otherwise.
 */
css_error node_has_attribute_substring(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match)
{
	dom_node *n = node;
	dom_string *name;
	dom_string *atr_val;
	dom_exception err;

	size_t vlen = lwc_string_length(value);

	if (vlen == 0) {
		*match = false;
		return CSS_OK;
	}

	err = dom_string_create_interned(
		(const uint8_t *) lwc_string_data(qname->name),
		lwc_string_length(qname->name), &name);
	if (err != DOM_NO_ERR)
		return CSS_NOMEM;

	err = dom_element_get_attribute(n, name, &atr_val);
	if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
		dom_string_unref(name);
		*match = false;
		return CSS_OK;
	}

	dom_string_unref(name);

	/* check for exact match */
	*match = dom_string_caseless_lwc_isequal(atr_val, value);

	/* check for prefix match */
	if (*match == false) {
		const char *vdata = lwc_string_data(value);
		const char *start = (const char *) dom_string_data(atr_val);
		size_t len = dom_string_byte_length(atr_val);
		const char *last_start = start + len - vlen;

		if (len >= vlen) {
			while (start <= last_start) {
				if (strncasecmp(start, vdata,
						vlen) == 0) {
					*match = true;
					break;
				}

				start++;
			}
		}
	}

	dom_string_unref(atr_val);

	return CSS_OK;
}
Exemplo n.º 3
0
/**
 * Callback to determine if a node has an attribute with the given name whose
 * value includes that given.
 *
 * \param pw     HTML document
 * \param node   DOM node
 * \param qname  Name to match
 * \param value  Value to match
 * \param match  Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_NOMEM on memory exhaustion.
 *
 * \post \a match will contain true if the node matches and false otherwise.
 */
css_error node_has_attribute_includes(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match)
{
	dom_node *n = node;
	dom_string *name;
	dom_string *atr_val;
	dom_exception err;
	size_t vlen = lwc_string_length(value);
	const char *p;
	const char *start;
	const char *end;

	*match = false;

	if (vlen == 0) {
		return CSS_OK;
	}

	err = dom_string_create_interned(
		(const uint8_t *) lwc_string_data(qname->name),
		lwc_string_length(qname->name), &name);
	if (err != DOM_NO_ERR)
		return CSS_NOMEM;

	err = dom_element_get_attribute(n, name, &atr_val);
	if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
		dom_string_unref(name);
		*match = false;
		return CSS_OK;
	}

	dom_string_unref(name);

	/* check for match */
	start = (const char *) dom_string_data(atr_val);
	end = start + dom_string_byte_length(atr_val);

	for (p = start; p <= end; p++) {
		if (*p == ' ' || *p == '\0') {
			if ((size_t) (p - start) == vlen &&
			    strncasecmp(start,
					lwc_string_data(value),
					vlen) == 0) {
				*match = true;
				break;
			}

			start = p + 1;
		}
	}

	dom_string_unref(atr_val);

	return CSS_OK;
}
Exemplo n.º 4
0
css_fixed css__number_from_lwc_string(lwc_string *string,
		bool int_only, size_t *consumed)
{
	if (string == NULL || lwc_string_length(string) == 0 || 
			consumed == NULL)
		return 0;

	return css__number_from_string(
			(uint8_t *)lwc_string_data(string),
			lwc_string_length(string),
			int_only,
			consumed);
}
Exemplo n.º 5
0
/**
 * Callback to determine if a node has an attribute with the given name whose
 * value dashmatches that given.
 *
 * \param pw     HTML document
 * \param node   DOM node
 * \param qname  Name to match
 * \param value  Value to match
 * \param match  Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_NOMEM on memory exhaustion.
 *
 * \post \a match will contain true if the node matches and false otherwise.
 */
css_error node_has_attribute_dashmatch(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match)
{
	dom_node *n = node;
	dom_string *name;
	dom_string *atr_val;
	dom_exception err;

	size_t vlen = lwc_string_length(value);

	if (vlen == 0) {
		*match = false;
		return CSS_OK;
	}

	err = dom_string_create_interned(
		(const uint8_t *) lwc_string_data(qname->name),
		lwc_string_length(qname->name), &name);
	if (err != DOM_NO_ERR)
		return CSS_NOMEM;

	err = dom_element_get_attribute(n, name, &atr_val);
	if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
		dom_string_unref(name);
		*match = false;
		return CSS_OK;
	}

	dom_string_unref(name);

	/* check for exact match */
	*match = dom_string_caseless_lwc_isequal(atr_val, value);

	/* check for dashmatch */
	if (*match == false) {
		const char *vdata = lwc_string_data(value);
		const char *data = (const char *) dom_string_data(atr_val);
		size_t len = dom_string_byte_length(atr_val);

		if (len > vlen && data[vlen] == '-' &&
		    strncasecmp(data, vdata, vlen) == 0) {
				*match = true;
		}
	}

	dom_string_unref(atr_val);

	return CSS_OK;
}
Exemplo n.º 6
0
/**
 * Try and find the correct RISC OS filetype from a download context.
 */
static nserror download_ro_filetype(download_context *ctx, bits *ftype_out)
{
	nsurl *url = download_context_get_url(ctx);
	bits ftype = 0;
	lwc_string *scheme;

	/* If the file is local try and read its filetype */
	scheme = nsurl_get_component(url, NSURL_SCHEME);
	if (scheme != NULL) {
		bool filescheme;
		if (lwc_string_isequal(scheme,
				       corestring_lwc_file,
				       &filescheme) != lwc_error_ok) {
			filescheme = false;
		}

		if (filescheme) {
			lwc_string *path = nsurl_get_component(url, NSURL_PATH);
			if (path != NULL && lwc_string_length(path) != 0) {
				char *raw_path;
				if (url_unescape(lwc_string_data(path),
						 lwc_string_length(path),
						 &raw_path) == NSERROR_OK) {
					ftype =	ro_filetype_from_unix_path(raw_path);
					free(raw_path);
				}
			}
		}
	}

	/* If we still don't have a filetype (i.e. failed reading local
	 * one or fetching a remote object), then use the MIME type.
	 */
	if (ftype == 0) {
		/* convert MIME type to RISC OS file type */
		os_error *error;
		const char *mime_type;

		mime_type = download_context_get_mime_type(ctx);
		error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype);
		if (error) {
			LOG("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess);
			ro_warn_user("MiscError", error->errmess);
			ftype = 0xffd;
		}
	}

	*ftype_out = ftype;
	return NSERROR_OK;
}
Exemplo n.º 7
0
/**
 * Parse a hash colour (#rgb or #rrggbb)
 *
 * \param data    Pointer to colour string
 * \param result  Pointer to location to receive result (AARRGGBB)
 * \return CSS_OK      on success,
 *         CSS_INVALID if the input is invalid
 */
css_error css__parse_hash_colour(lwc_string *data, uint32_t *result)
{
	uint8_t r = 0, g = 0, b = 0, a = 0xff;
	size_t len = lwc_string_length(data);
	const char *input = lwc_string_data(data);

	if (len == 3 &&	isHex(input[0]) && isHex(input[1]) &&
			isHex(input[2])) {
		r = charToHex(input[0]);
		g = charToHex(input[1]);
		b = charToHex(input[2]);

		r |= (r << 4);
		g |= (g << 4);
		b |= (b << 4);
	} else if (len == 6 && isHex(input[0]) && isHex(input[1]) &&
			isHex(input[2]) && isHex(input[3]) &&
			isHex(input[4]) && isHex(input[5])) {
		r = (charToHex(input[0]) << 4);
		r |= charToHex(input[1]);
		g = (charToHex(input[2]) << 4);
		g |= charToHex(input[3]);
		b = (charToHex(input[4]) << 4);
		b |= charToHex(input[5]);
	} else
		return CSS_INVALID;

	*result = (a << 24) | (r << 16) | (g << 8) | b;

	return CSS_OK;
}
Exemplo n.º 8
0
css_error node_has_attribute_substring(void *pw, void *n,
		const css_qname *qname,
		lwc_string *value,
		bool *match)
{
	node *node = n;
	uint32_t i;
	UNUSED(pw);

	*match = false;
	
	for (i = 0; i < node->n_attrs; i++) {
		assert(lwc_string_caseless_isequal(
				node->attrs[i].name, qname->name, match) == 
				lwc_error_ok);
		if (*match == true)
			break;
	}
	
	if (*match == true) {
		size_t len = lwc_string_length(node->attrs[i].value);
		const char *data = lwc_string_data(node->attrs[i].value);

		size_t vlen = lwc_string_length(value);
		const char *vdata = lwc_string_data(value);

		const char *last_start = data + len - vlen;

		if (len < vlen)
			*match = false;
		else {
			while (data <= last_start) {
				if (strncasecmp(data, vdata, vlen) == 0) {
					*match = true;
					break;
				}

				data++;
			}

			if (data > last_start)
				*match = false;
		}
	}

	return CSS_OK;
}
Exemplo n.º 9
0
/**
 * Initialise a CSS content
 *
 * \param c       Content to initialise
 * \param params  Content-Type parameters
 * \return true on success, false on failure
 */
nserror nscss_create(const content_handler *handler, 
		lwc_string *imime_type,	const http_parameter *params,
		llcache_handle *llcache, const char *fallback_charset,
		bool quirks, struct content **c)
{
	nscss_content *result;
	const char *charset = NULL;
	const char *xnsbase = NULL;
	lwc_string *charset_value = NULL;
	union content_msg_data msg_data;
	nserror error;

	result = calloc(1, sizeof(nscss_content));
	if (result == NULL)
		return NSERROR_NOMEM;

	error = content__init(&result->base, handler, imime_type,
			params, llcache, fallback_charset, quirks);
	if (error != NSERROR_OK) {
		free(result);
		return error;
	}

	/* Find charset specified on HTTP layer, if any */
	error = http_parameter_list_find_item(params, css_charset, 
			&charset_value);
	if (error != NSERROR_OK || lwc_string_length(charset_value) == 0) {
		/* No charset specified, use fallback, if any */
		/** \todo libcss will take this as gospel, which is wrong */
		charset = fallback_charset;
	} else {
		charset = lwc_string_data(charset_value);
	}

	/* Compute base URL for stylesheet */
	xnsbase = llcache_handle_get_header(llcache, "X-NS-Base");
	if (xnsbase == NULL) {
		xnsbase = nsurl_access(content_get_url(&result->base));
	}

	error = nscss_create_css_data(&result->data, 
			xnsbase, charset, result->base.quirks, 
			nscss_content_done, result);
	if (error != NSERROR_OK) {
		msg_data.error = messages_get("NoMemory");
		content_broadcast(&result->base, CONTENT_MSG_ERROR, msg_data);
		if (charset_value != NULL)
			lwc_string_unref(charset_value);
		free(result);
		return error;
	}

	if (charset_value != NULL)
		lwc_string_unref(charset_value);

	*c = (struct content *) result;

	return NSERROR_OK;
}
Exemplo n.º 10
0
static void netsurf_lwc_iterator(lwc_string *str, void *pw)
{
	fprintf(stderr,
		"[%3u] %.*s",
		str->refcnt,
		(int)lwc_string_length(str),
		lwc_string_data(str));
}
Exemplo n.º 11
0
static void
printing_lwc_iterator(lwc_string *str, void *pw)
{
	UNUSED(pw);
	
	printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str));
	fail_because_lwc_leaked = true;
}
Exemplo n.º 12
0
css_error node_has_attribute_dashmatch(void *pw, void *n,
		const css_qname *qname,
		lwc_string *value,
		bool *match)
{
	node *node = n;
	uint32_t i;
	size_t vlen = lwc_string_length(value);
	UNUSED(pw);

	*match = false;
	
	for (i = 0; i < node->n_attrs; i++) {
		assert(lwc_string_caseless_isequal(
				node->attrs[i].name, qname->name, match) == 
				lwc_error_ok);
		if (*match == true)
			break;
	}

	if (*match == true) {
		const char *p;
		const char *start = lwc_string_data(node->attrs[i].value);
		const char *end = start + 
				lwc_string_length(node->attrs[i].value);
		
		*match = false;
		
		for (p = start; p < end; p++) {
			if (*p == '-') {
				if ((size_t) (p - start) == vlen && 
						strncasecmp(start,
							lwc_string_data(value), 
							vlen) == 0) {
					*match = true;
					break;
				}

				start = p + 1;
			}
		}
	}

	return CSS_OK;
}
Exemplo n.º 13
0
END_TEST

START_TEST (test_lwc_extract_data_ok)
{
    fail_unless(memcmp("one",
                       lwc_string_data(intern_one),
                       lwc_string_length(intern_one)) == 0,
                "Extracting data ptr etc failed");
}
Exemplo n.º 14
0
/** Get the byte length of this dom_string 
 *
 * \param str	The dom_string object
 */
size_t dom_string_byte_length(const dom_string *str)
{
	dom_string_internal *istr = (dom_string_internal *) str;
	if (istr->type == DOM_STRING_CDATA) {
		return istr->data.cdata.len;
	} else {
		return lwc_string_length(istr->data.intern);
	}
}
Exemplo n.º 15
0
END_TEST

START_TEST (test_lwc_string_is_nul_terminated)
{
    lwc_string *new_ONE;

    fail_unless(lwc_intern_string("ONE", 3, &new_ONE) == lwc_error_ok,
                "Failure interning 'ONE'");

    fail_unless(lwc_string_data(new_ONE)[lwc_string_length(new_ONE)] == '\0',
                "Interned string isn't NUL terminated");
}
Exemplo n.º 16
0
/**
 * Callback to determine if a node has an attribute with given name and value.
 *
 * \param pw     HTML document
 * \param node   DOM node
 * \param qname  Name to match
 * \param value  Value to match
 * \param match  Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_NOMEM on memory exhaustion.
 *
 * \post \a match will contain true if the node matches and false otherwise.
 */
css_error node_has_attribute_equal(void *pw, void *node,
		const css_qname *qname, lwc_string *value,
		bool *match)
{
	dom_node *n = node;
	dom_string *name;
	dom_string *atr_val;
	dom_exception err;

	size_t vlen = lwc_string_length(value);

	if (vlen == 0) {
		*match = false;
		return CSS_OK;
	}

	err = dom_string_create_interned(
		(const uint8_t *) lwc_string_data(qname->name),
		lwc_string_length(qname->name), &name);
	if (err != DOM_NO_ERR)
		return CSS_NOMEM;

	err = dom_element_get_attribute(n, name, &atr_val);
	if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
		dom_string_unref(name);
		*match = false;
		return CSS_OK;
	}

	dom_string_unref(name);

	*match = dom_string_caseless_lwc_isequal(atr_val, value);

	dom_string_unref(atr_val);

	return CSS_OK;
}
/**
 * Parse widows
 *
 * \param c	  Parsing context
 * \param vector  Vector of tokens to process
 * \param ctx	  Pointer to vector iteration context
 * \param result  resulting style
 * \return CSS_OK on success,
 *	   CSS_NOMEM on memory exhaustion,
 *	   CSS_INVALID if the input is not valid
 *
 * Post condition: \a *ctx is updated with the next token to process
 *		   If the input is invalid, then \a *ctx remains unchanged.
 */
css_error css__parse_widows(css_language *c,
		const parserutils_vector *vector, int *ctx,
		css_style *result)
{
	int orig_ctx = *ctx;
	css_error error;
	const css_token *token;
	bool match;

	token = parserutils_vector_iterate(vector, ctx);
	if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_NUMBER))) {
		*ctx = orig_ctx;
		return CSS_INVALID;
	}

	if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[INHERIT], &match) == lwc_error_ok && match)) {
			error = css_stylesheet_style_inherit(result, CSS_PROP_WIDOWS);
	} else if (token->type == CSS_TOKEN_NUMBER) {
		css_fixed num = 0;
		size_t consumed = 0;

		num = css__number_from_lwc_string(token->idata, true, &consumed);
		/* Invalid if there are trailing characters */
		if (consumed != lwc_string_length(token->idata)) {
			*ctx = orig_ctx;
			return CSS_INVALID;
		}
		if (num<0) {
			*ctx = orig_ctx;
			return CSS_INVALID;
		}

		error = css__stylesheet_style_appendOPV(result, CSS_PROP_WIDOWS, 0, WIDOWS_SET);
		if (error != CSS_OK) {
			*ctx = orig_ctx;
			return error;
		}

		error = css__stylesheet_style_append(result, num);
	} else {
		error = CSS_INVALID;
	}

	if (error != CSS_OK)
		*ctx = orig_ctx;
	
	return error;
}
Exemplo n.º 18
0
css_error node_has_name(void *pw, void *n,
		const css_qname *qname,
		bool *match)
{
	node *node = n;
	UNUSED(pw);

	if (lwc_string_length(qname->name) == 1 &&
			lwc_string_data(qname->name)[0] == '*')
		*match = true;
	else
		assert(lwc_string_caseless_isequal(node->name, 
			qname->name, match) == lwc_error_ok);

	return CSS_OK;
}
Exemplo n.º 19
0
/**
 * Case insensitively compare DOM string with lwc_string
 *
 * \param s1  The first string to compare
 * \param s2  The second string to compare
 * \return true if strings match, false otherwise
 *
 * Returns false if either are NULL.
 */
bool dom_string_caseless_lwc_isequal(const dom_string *s1, lwc_string *s2)
{
	size_t len;
	const uint8_t *d1 = NULL;
	const uint8_t *d2 = NULL;
	dom_string_internal *is1 = (dom_string_internal *) s1;

	if (s1 == NULL || s2 == NULL)
		return false;

	if (is1->type == DOM_STRING_INTERNED) {
		bool match;

		if (lwc_string_caseless_isequal(is1->data.intern, s2, &match) != lwc_error_ok)
			return false;

		return match;
	}

	len = dom_string_byte_length(s1);

	if (len != lwc_string_length(s2))
		return false;

	d1 = (const uint8_t *) dom_string_data(s1);
	d2 = (const uint8_t *) lwc_string_data(s2);

	while (len > 0) {
		if (dolower(*d1) != dolower(*d2))
			return false;

		d1++;
		d2++;
		len--;
	}

	return true;
}
Exemplo n.º 20
0
/**
 * Callback to determine if a node has an attribute with the given name.
 *
 * \param pw     HTML document
 * \param node   DOM node
 * \param qname  Name to match
 * \param match  Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_NOMEM on memory exhaustion.
 *
 * \post \a match will contain true if the node matches and false otherwise.
 */
css_error node_has_attribute(void *pw, void *node,
		const css_qname *qname, bool *match)
{
	dom_node *n = node;
	dom_string *name;
	dom_exception err;

	err = dom_string_create_interned(
			(const uint8_t *) lwc_string_data(qname->name),
			lwc_string_length(qname->name), &name);
	if (err != DOM_NO_ERR)
		return CSS_NOMEM;

	err = dom_element_has_attribute(n, name, match);
	if (err != DOM_NO_ERR) {
		dom_string_unref(name);
		return CSS_OK;
	}

	dom_string_unref(name);

	return CSS_OK;
}
Exemplo n.º 21
0
/**
 * Case sensitively compare DOM string with lwc_string
 *
 * \param s1  The first string to compare
 * \param s2  The second string to compare
 * \return true if strings match, false otherwise
 *
 * Returns false if either are NULL.
 */
bool dom_string_lwc_isequal(const dom_string *s1, lwc_string *s2)
{
	size_t len;
	dom_string_internal *is1 = (dom_string_internal *) s1;

	if (s1 == NULL || s2 == NULL)
		return false;

	if (is1->type == DOM_STRING_INTERNED) {
		bool match;

		(void) lwc_string_isequal(is1->data.intern, s2, &match);

		return match;
	}

	/* Handle non-interned case */
	len = dom_string_byte_length(s1);

	if (len != lwc_string_length(s2))
		return false;

	return 0 == memcmp(dom_string_data(s1), lwc_string_data(s2), len);
}
Exemplo n.º 22
0
END_TEST

START_TEST (test_lwc_string_length_aborts)
{
    lwc_string_length(NULL);
}
Exemplo n.º 23
0
void ro_gui_401login_open(nsurl *url, lwc_string *host, const char *realm,
		nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
	struct session_401 *session;
	wimp_w w;
	const char *auth;

	session = calloc(1, sizeof(struct session_401));
	if (!session) {
		warn_user("NoMemory", 0);
		return;
	}

	session->url = nsurl_ref(url);
	if (realm == NULL)
		realm = "Secure Area";
        auth = urldb_get_auth_details(session->url, realm);
	if (auth == NULL) {
		session->uname[0] = '\0';
		session->pwd[0] = '\0';
	} else {
		const char *pwd;
		size_t pwd_len;

		pwd = strchr(auth, ':');
		assert(pwd && pwd < auth + sizeof(session->uname));
		memcpy(session->uname, auth, pwd - auth);
		session->uname[pwd - auth] = '\0';
		++pwd;
		pwd_len = strlen(pwd);
		assert(pwd_len < sizeof(session->pwd));
		memcpy(session->pwd, pwd, pwd_len);
		session->pwd[pwd_len] = '\0';
	}
	session->host = lwc_string_ref(host);
	session->realm = strdup(realm);
	session->cb = cb;
	session->cbpw = cbpw;

	if (!session->realm) {
		nsurl_unref(session->url);
		lwc_string_unref(session->host);
		free(session);
		warn_user("NoMemory", 0);
		return;
	}

	/* fill in download window icons */
	dialog_401_template->icons[ICON_401LOGIN_HOST].data.
			indirected_text.text =
					(char *)lwc_string_data(session->host);
	dialog_401_template->icons[ICON_401LOGIN_HOST].data.
			indirected_text.size =
					lwc_string_length(session->host) + 1;
	dialog_401_template->icons[ICON_401LOGIN_REALM].data.
			indirected_text.text = session->realm;
	dialog_401_template->icons[ICON_401LOGIN_REALM].data.
			indirected_text.size = strlen(session->realm) + 1;
	dialog_401_template->icons[ICON_401LOGIN_USERNAME].data.
			indirected_text.text = session->uname;
	dialog_401_template->icons[ICON_401LOGIN_USERNAME].data.
			indirected_text.size = sizeof(session->uname);
	dialog_401_template->icons[ICON_401LOGIN_PASSWORD].data.
			indirected_text.text = session->pwd;
	dialog_401_template->icons[ICON_401LOGIN_PASSWORD].data.
			indirected_text.size = sizeof(session->pwd);

	/* create and open the window */
	w = wimp_create_window(dialog_401_template);

	ro_gui_wimp_event_register_text_field(w, ICON_401LOGIN_USERNAME);
	ro_gui_wimp_event_register_text_field(w, ICON_401LOGIN_PASSWORD);
	ro_gui_wimp_event_register_cancel(w, ICON_401LOGIN_CANCEL);
	ro_gui_wimp_event_register_ok(w, ICON_401LOGIN_LOGIN,
			ro_gui_401login_apply);
	ro_gui_wimp_event_register_close_window(w, ro_gui_401login_close);
	ro_gui_wimp_event_set_user_data(w, session);

	ro_gui_dialog_open_persistent(NULL, w, false);
}
Exemplo n.º 24
0
/**
 * Parse line-height
 *
 * \param c       Parsing context
 * \param vector  Vector of tokens to process
 * \param ctx     Pointer to vector iteration context
 * \param result  Pointer to location to receive resulting style
 * \return CSS_OK on success,
 *         CSS_NOMEM on memory exhaustion,
 *         CSS_INVALID if the input is not valid
 *
 * Post condition: \a *ctx is updated with the next token to process
 *                 If the input is invalid, then \a *ctx remains unchanged.
 */
css_error parse_line_height(css_language *c, 
		const parserutils_vector *vector, int *ctx, 
		css_style **result)
{
	int orig_ctx = *ctx;
	css_error error;
	const css_token *token;
	uint8_t flags = 0;
	uint16_t value = 0;
	uint32_t opv;
	css_fixed length = 0;
	uint32_t unit = 0;
	uint32_t required_size;
	bool match;

	/* number | length | percentage | IDENT(normal, inherit) */
	token = parserutils_vector_peek(vector, *ctx);
	if (token == NULL) {
		*ctx = orig_ctx;
		return CSS_INVALID;
	}

	if (token->type == CSS_TOKEN_IDENT &&
			(lwc_string_caseless_isequal(
			token->idata, c->strings[INHERIT],
			&match) == lwc_error_ok && match)) {
		parserutils_vector_iterate(vector, ctx);
		flags = FLAG_INHERIT;
	} else if (token->type == CSS_TOKEN_IDENT &&
			(lwc_string_caseless_isequal(
			token->idata, c->strings[NORMAL],
			&match) == lwc_error_ok && match)) {
		parserutils_vector_iterate(vector, ctx);
		value = LINE_HEIGHT_NORMAL;
	} else if (token->type == CSS_TOKEN_NUMBER) {
		size_t consumed = 0;
		length = number_from_lwc_string(token->idata, false, &consumed);
		if (consumed != lwc_string_length(token->idata)) {
			*ctx = orig_ctx;
			return CSS_INVALID;
		}

		/* Negative values are illegal */
		if (length < 0) {
			*ctx = orig_ctx;
			return CSS_INVALID;
		}

		parserutils_vector_iterate(vector, ctx);
		value = LINE_HEIGHT_NUMBER;
	} else {
		error = parse_unit_specifier(c, vector, ctx, UNIT_PX,
				&length, &unit);
		if (error != CSS_OK) {
			*ctx = orig_ctx;
			return error;
		}

		if (unit & UNIT_ANGLE || unit & UNIT_TIME || unit & UNIT_FREQ) {
			*ctx = orig_ctx;
			return CSS_INVALID;
		}

		/* Negative values are illegal */
		if (length < 0) {
			*ctx = orig_ctx;
			return CSS_INVALID;
		}

		value = LINE_HEIGHT_DIMENSION;
	}

	opv = buildOPV(CSS_PROP_LINE_HEIGHT, flags, value);

	required_size = sizeof(opv);
	if ((flags & FLAG_INHERIT) == false && value == LINE_HEIGHT_NUMBER)
		required_size += sizeof(length);
	else if ((flags & FLAG_INHERIT) == false && 
			value == LINE_HEIGHT_DIMENSION)
		required_size += sizeof(length) + sizeof(unit);

	/* Allocate result */
	error = css_stylesheet_style_create(c->sheet, required_size, result);
	if (error != CSS_OK) {
		*ctx = orig_ctx;
		return error;
	}

	/* Copy the bytecode to it */
	memcpy((*result)->bytecode, &opv, sizeof(opv));
	if ((flags & FLAG_INHERIT) == false && (value == LINE_HEIGHT_NUMBER || 
			value == LINE_HEIGHT_DIMENSION))
		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv),
				&length, sizeof(length));
	if ((flags & FLAG_INHERIT) == false && value == LINE_HEIGHT_DIMENSION)
		memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) +
				sizeof(length), &unit, sizeof(unit));

	return CSS_OK;
}
Exemplo n.º 25
0
int main(int argc, char **argv)
{
	css_stylesheet_params params;
	css_stylesheet *sheet;
	FILE *fp;
	size_t len, origlen;
#define CHUNK_SIZE (4096)
	uint8_t buf[CHUNK_SIZE];
	css_error error;
	int count;

	if (argc != 2) {
		printf("Usage: %s <filename>\n", argv[0]);
		return 1;
	}

	params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
	params.level = CSS_LEVEL_21;
	params.charset = "UTF-8";
	params.url = argv[1];
	params.title = NULL;
	params.allow_quirks = false;
	params.inline_style = false;
	params.resolve = resolve_url;
	params.resolve_pw = NULL;
	params.import = NULL;
	params.import_pw = NULL;
	params.color = NULL;
	params.color_pw = NULL;
	params.font = NULL;
	params.font_pw = NULL;

	for (count = 0; count < ITERATIONS; count++) {

		assert(css_stylesheet_create(&params, myrealloc, NULL, 
				&sheet) == CSS_OK);

		fp = fopen(argv[1], "rb");
		if (fp == NULL) {
			printf("Failed opening %s\n", argv[1]);
			return 1;
		}

		fseek(fp, 0, SEEK_END);
		origlen = len = ftell(fp);
		fseek(fp, 0, SEEK_SET);

		while (len >= CHUNK_SIZE) {
			size_t read = fread(buf, 1, CHUNK_SIZE, fp);
			assert(read == CHUNK_SIZE);

			error = css_stylesheet_append_data(sheet, buf, 
					CHUNK_SIZE);
			assert(error == CSS_OK || error == CSS_NEEDDATA);

			len -= CHUNK_SIZE;
		}

		if (len > 0) {
			size_t read = fread(buf, 1, len, fp);
			assert(read == len);

			error = css_stylesheet_append_data(sheet, buf, len);
			assert(error == CSS_OK || error == CSS_NEEDDATA);

			len = 0;
		}

		fclose(fp);

		error = css_stylesheet_data_done(sheet);
		assert(error == CSS_OK || error == CSS_IMPORTS_PENDING);

		while (error == CSS_IMPORTS_PENDING) {
			lwc_string *url;
			uint64_t media;

			error = css_stylesheet_next_pending_import(sheet,
					&url, &media);
			assert(error == CSS_OK || error == CSS_INVALID);

			if (error == CSS_OK) {
				css_stylesheet *import;
				char *buf = alloca(lwc_string_length(url) + 1);

				memcpy(buf, lwc_string_data(url), 
						lwc_string_length(url));
				buf[lwc_string_length(url)] = '\0';

				params.url = buf;

				assert(css_stylesheet_create(&params,
					myrealloc, NULL, &import) == CSS_OK);

				assert(css_stylesheet_data_done(import) == 
					CSS_OK);

				assert(css_stylesheet_register_import(sheet,
					import) == CSS_OK);

				css_stylesheet_destroy(import);

				error = CSS_IMPORTS_PENDING;
			}
		}

#if DUMP_CSS
		{
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
			char *out;
			size_t outsize = max(16384, origlen * 8);
			size_t outlen = outsize;
			size_t written;
			out = malloc(outsize);
			assert(out != NULL);
			dump_sheet(sheet, out, &outlen);
			written = fwrite(out, 1, outsize - outlen, stdout);
			assert(written == outsize - outlen);
			free(out);
		}
#endif

		css_stylesheet_destroy(sheet);
	}

	printf("PASS\n");
        
	return 0;
}
Exemplo n.º 26
0
/**
 * Parse a unit specifier
 *
 * \param c             Parsing context
 * \param vector        Vector of tokens to process
 * \param ctx           Pointer to current vector iteration context
 * \param default_unit  The default unit to use if none specified
 * \param length        Pointer to location to receive length
 * \param unit          Pointer to location to receive unit
 * \return CSS_OK      on success,
 *         CSS_INVALID if the tokens do not form a valid unit
 *
 * Post condition: \a *ctx is updated with the next token to process
 *                 If the input is invalid, then \a *ctx remains unchanged.
 */
css_error css__parse_unit_specifier(css_language *c,
		const parserutils_vector *vector, int *ctx,
		uint32_t default_unit,
		css_fixed *length, uint32_t *unit)
{
	int orig_ctx = *ctx;
	const css_token *token;
	css_fixed num;
	size_t consumed = 0;
	css_error error;

	consumeWhitespace(vector, ctx);

	token = parserutils_vector_iterate(vector, ctx);
	if (token == NULL || (token->type != CSS_TOKEN_DIMENSION &&
			token->type != CSS_TOKEN_NUMBER &&
			token->type != CSS_TOKEN_PERCENTAGE)) {
		*ctx = orig_ctx;
		return CSS_INVALID;
	}

	num = css__number_from_lwc_string(token->idata, false, &consumed);

	if (token->type == CSS_TOKEN_DIMENSION) {
		size_t len = lwc_string_length(token->idata);
		const char *data = lwc_string_data(token->idata);
		css_unit temp_unit = CSS_UNIT_PX;

		error = css__parse_unit_keyword(data + consumed, len - consumed,
				&temp_unit);
		if (error != CSS_OK) {
			*ctx = orig_ctx;
			return error;
		}

		*unit = (uint32_t) temp_unit;
	} else if (token->type == CSS_TOKEN_NUMBER) {
		/* Non-zero values are permitted in quirks mode */
		if (num != 0) {
			if (c->sheet->quirks_allowed) {
				c->sheet->quirks_used = true;
			} else {
				*ctx = orig_ctx;
				return CSS_INVALID;
			}
		}

		*unit = default_unit;

		if (c->sheet->quirks_allowed) {
			/* Also, in quirks mode, we need to cater for
			 * dimensions separated from their units by whitespace
			 * (e.g. "0 px")
			 */
			int temp_ctx = *ctx;
			css_unit temp_unit;

			consumeWhitespace(vector, &temp_ctx);

			/* Try to parse the unit keyword, ignoring errors */
			token = parserutils_vector_iterate(vector, &temp_ctx);
			if (token != NULL && token->type == CSS_TOKEN_IDENT) {
				error = css__parse_unit_keyword(
						lwc_string_data(token->idata),
						lwc_string_length(token->idata),
						&temp_unit);
				if (error == CSS_OK) {
					c->sheet->quirks_used = true;
					*ctx = temp_ctx;
					*unit = (uint32_t) temp_unit;
				}
			}
		}
	} else {
		/* Percentage -- number must be entire token data */
		if (consumed != lwc_string_length(token->idata)) {
			*ctx = orig_ctx;
			return CSS_INVALID;
		}
		*unit = UNIT_PCT;
	}

	*length = num;

	return CSS_OK;
}
Exemplo n.º 27
0
void nsbeos_gui_view_source(struct hlcache_handle *content)
{
	char *temp_name;
	bool done = false;
	BPath path;
	status_t err;
	size_t size;
	const char *source = content_get_source_data(content, &size);

	if (!content || !source) {
		warn_user("MiscError", "No document source");
		return;
	}

	/* try to load local files directly. */
	temp_name = url_to_path(nsurl_access(hlcache_handle_get_url(content)));
	if (temp_name) {
		path.SetTo(temp_name);
		BEntry entry;
		if (entry.SetTo(path.Path()) >= B_OK 
			&& entry.Exists() && entry.IsFile())
			done = true;
	}
	if (!done) {
		/* We cannot release the requested filename until after it
		 * has finished being used. As we can't easily find out when
		 * this is, we simply don't bother releasing it and simply
		 * allow it to be re-used next time NetSurf is started. The
		 * memory overhead from doing this is under 1 byte per
		 * filename. */
		const char *filename = filename_request();
		if (!filename) {
			warn_user("NoMemory", 0);
			return;
		}
		path.SetTo(TEMP_FILENAME_PREFIX);
		path.Append(filename);
		BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
		err = file.InitCheck();
		if (err < B_OK) {
			warn_user("IOError", strerror(err));
			return;
		}
		err = file.Write(source, size);
		if (err < B_OK) {
			warn_user("IOError", strerror(err));
			return;
		}
		lwc_string *mime = content_get_mime_type(content);
		if (mime) {
			file.WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0LL, 
				lwc_string_data(mime), lwc_string_length(mime) + 1);
			lwc_string_unref(mime);
		}
		
	}

	entry_ref ref;
	if (get_ref_for_path(path.Path(), &ref) < B_OK)
		return;

	BMessage m(B_REFS_RECEIVED);
	m.AddRef("refs", &ref);


	// apps to try
	const char *editorSigs[] = {
		"application/x-vnd.beunited.pe",
		"application/x-vnd.XEmacs",
		"application/x-vnd.Haiku-StyledEdit",
		"application/x-vnd.Be-STEE",
		"application/x-vnd.yT-STEE",
		NULL
	};
	int i;
	for (i = 0; editorSigs[i]; i++) {
		team_id team = -1;
		{
			BMessenger msgr(editorSigs[i], team);
			if (msgr.SendMessage(&m) >= B_OK)
				break;
		}
		
		err = be_roster->Launch(editorSigs[i], (BMessage *)&m, &team);
		if (err >= B_OK)
			break;
	}
}
Exemplo n.º 28
0
/**
 * Parse a colour specifier
 *
 * \param c       Parsing context
 * \param vector  Vector of tokens to process
 * \param ctx     Pointer to vector iteration context
 * \param value   Pointer to location to receive value
 * \param result  Pointer to location to receive result (AARRGGBB)
 * \return CSS_OK      on success,
 *         CSS_INVALID if the input is invalid
 *
 * Post condition: \a *ctx is updated with the next token to process
 *                 If the input is invalid, then \a *ctx remains unchanged.
 */
css_error css__parse_colour_specifier(css_language *c,
		const parserutils_vector *vector, int *ctx,
		uint16_t *value, uint32_t *result)
{
	int orig_ctx = *ctx;
	const css_token *token;
	bool match;
	css_error error;

	consumeWhitespace(vector, ctx);

	/* IDENT(<colour name>) | 
	 * HASH(rgb | rrggbb) |
	 * FUNCTION(rgb) [ [ NUMBER | PERCENTAGE ] ',' ] {3} ')'
	 * FUNCTION(rgba) [ [ NUMBER | PERCENTAGE ] ',' ] {4} ')'
	 * FUNCTION(hsl) ANGLE ',' PERCENTAGE ',' PERCENTAGE  ')'
	 * FUNCTION(hsla) ANGLE ',' PERCENTAGE ',' PERCENTAGE ',' NUMBER ')'
	 *
	 * For quirks, NUMBER | DIMENSION | IDENT, too
	 * I.E. "123456" -> NUMBER, "1234f0" -> DIMENSION, "f00000" -> IDENT
	 */
	token = parserutils_vector_iterate(vector, ctx);
	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
			token->type != CSS_TOKEN_HASH &&
			token->type != CSS_TOKEN_FUNCTION)) {
		if (c->sheet->quirks_allowed == false ||
				token == NULL ||
				(token->type != CSS_TOKEN_NUMBER &&
				token->type != CSS_TOKEN_DIMENSION))
			goto invalid;
	}

	if (token->type == CSS_TOKEN_IDENT) {
		if ((lwc_string_caseless_isequal(
				token->idata, c->strings[TRANSPARENT],
				&match) == lwc_error_ok && match)) {
			*value = COLOR_TRANSPARENT;
			*result = 0; /* black transparent */
			return CSS_OK;
		} else if ((lwc_string_caseless_isequal(
				token->idata, c->strings[CURRENTCOLOR],
				&match) == lwc_error_ok && match)) {
			*value = COLOR_CURRENT_COLOR;
			*result = 0;
			return CSS_OK;
		}

		error = css__parse_named_colour(c, token->idata, result);
		if (error != CSS_OK && c->sheet->quirks_allowed) {
			error = css__parse_hash_colour(token->idata, result);
			if (error == CSS_OK)
				c->sheet->quirks_used = true;
		}

		if (error != CSS_OK)
			goto invalid;
	} else if (token->type == CSS_TOKEN_HASH) {
		error = css__parse_hash_colour(token->idata, result);
		if (error != CSS_OK)
			goto invalid;
	} else if (c->sheet->quirks_allowed &&
			token->type == CSS_TOKEN_NUMBER) {
		error = css__parse_hash_colour(token->idata, result);
		if (error == CSS_OK)
			c->sheet->quirks_used = true;
		else
			goto invalid;
	} else if (c->sheet->quirks_allowed &&
			token->type == CSS_TOKEN_DIMENSION) {
		error = css__parse_hash_colour(token->idata, result);
		if (error == CSS_OK)
			c->sheet->quirks_used = true;
		else
			goto invalid;
	} else if (token->type == CSS_TOKEN_FUNCTION) {
		uint8_t r = 0, g = 0, b = 0, a = 0xff;
		int colour_channels = 0;

		if ((lwc_string_caseless_isequal(
				token->idata, c->strings[RGB],
				&match) == lwc_error_ok && match)) {
			colour_channels = 3;
		} else if ((lwc_string_caseless_isequal(
				token->idata, c->strings[RGBA],
				&match) == lwc_error_ok && match)) {
			colour_channels = 4;
		} if ((lwc_string_caseless_isequal(
				token->idata, c->strings[HSL],
				&match) == lwc_error_ok && match)) {
			colour_channels = 5;
		} else if ((lwc_string_caseless_isequal(
				token->idata, c->strings[HSLA],
				&match) == lwc_error_ok && match)) {
			colour_channels = 6;
		}

		if (colour_channels == 3 || colour_channels == 4) {
			int i;
			css_token_type valid = CSS_TOKEN_NUMBER;
			uint8_t *components[4] = { &r, &g, &b, &a };

			for (i = 0; i < colour_channels; i++) {
				uint8_t *component;
				css_fixed num;
				size_t consumed = 0;
				int32_t intval;
				bool int_only;

				component = components[i];

				consumeWhitespace(vector, ctx);

				token = parserutils_vector_peek(vector, *ctx);
				if (token == NULL || (token->type !=
						CSS_TOKEN_NUMBER &&
						token->type !=
						CSS_TOKEN_PERCENTAGE))
					goto invalid;

				if (i == 0)
					valid = token->type;
				else if (i < 3 && token->type != valid)
					goto invalid;

				/* The alpha channel may be a float */
				if (i < 3)
					int_only = (valid == CSS_TOKEN_NUMBER);
				else
					int_only = false;

				num = css__number_from_lwc_string(token->idata,
						int_only, &consumed);
				if (consumed != lwc_string_length(token->idata))
					goto invalid;

				if (valid == CSS_TOKEN_NUMBER) {
					if (i == 3) {
						/* alpha channel */
						intval = FIXTOINT(
							FMUL(num, F_255));
					} else {
						/* colour channels */
						intval = FIXTOINT(num);
					}
				} else {
					intval = FIXTOINT(
						FDIV(FMUL(num, F_255), F_100));
				}

				if (intval > 255)
					*component = 255;
				else if (intval < 0)
					*component = 0;
				else
					*component = intval;

				parserutils_vector_iterate(vector, ctx);

				consumeWhitespace(vector, ctx);

				token = parserutils_vector_peek(vector, *ctx);
				if (token == NULL)
					goto invalid;

				if (i != (colour_channels - 1) &&
						tokenIsChar(token, ',')) {
					parserutils_vector_iterate(vector, ctx);
				} else if (i == (colour_channels - 1) &&
						tokenIsChar(token, ')')) {
					parserutils_vector_iterate(vector, ctx);
				} else {
					goto invalid;
				}
			}
		} else if (colour_channels == 5 || colour_channels == 6) {
			/* hue - saturation - lightness */
			size_t consumed = 0;
			css_fixed hue, sat, lit;
			int32_t alpha = 255;

			/* hue is a number without a unit representing an 
			 * angle (0-360) degrees  
			 */
			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if ((token == NULL) || (token->type != CSS_TOKEN_NUMBER))
				goto invalid;

			hue = css__number_from_lwc_string(token->idata, false, &consumed);
			if (consumed != lwc_string_length(token->idata))
				goto invalid; /* failed to consume the whole string as a number */

			/* Normalise hue to the range [0, 360) */
			while (hue < 0)
				hue += F_360;
			while (hue >= F_360)
				hue -= F_360;

			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if (!tokenIsChar(token, ','))
				goto invalid;


			/* saturation */
			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if ((token == NULL) || (token->type != CSS_TOKEN_PERCENTAGE))
				goto invalid;

			sat = css__number_from_lwc_string(token->idata, false, &consumed);
			if (consumed != lwc_string_length(token->idata))
				goto invalid; /* failed to consume the whole string as a number */

			/* Normalise saturation to the range [0, 100] */
			if (sat < INTTOFIX(0))
				sat = INTTOFIX(0);
			else if (sat > INTTOFIX(100))
				sat = INTTOFIX(100);

			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if (!tokenIsChar(token, ','))
				goto invalid;


			/* lightness */
			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if ((token == NULL) || (token->type != CSS_TOKEN_PERCENTAGE))
				goto invalid;

			lit = css__number_from_lwc_string(token->idata, false, &consumed);
			if (consumed != lwc_string_length(token->idata))
				goto invalid; /* failed to consume the whole string as a number */

			/* Normalise lightness to the range [0, 100] */
			if (lit < INTTOFIX(0))
				lit = INTTOFIX(0);
			else if (lit > INTTOFIX(100))
				lit = INTTOFIX(100);

			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);

			if (colour_channels == 6) {
				/* alpha */

				if (!tokenIsChar(token, ','))
					goto invalid;
			
				consumeWhitespace(vector, ctx);

				token = parserutils_vector_iterate(vector, ctx);
				if ((token == NULL) || (token->type != CSS_TOKEN_NUMBER))
					goto invalid;

				alpha = css__number_from_lwc_string(token->idata, false, &consumed);
				if (consumed != lwc_string_length(token->idata))
					goto invalid; /* failed to consume the whole string as a number */
				
				alpha = FIXTOINT(FMUL(alpha, F_255));

				consumeWhitespace(vector, ctx);

				token = parserutils_vector_iterate(vector, ctx);

			}

			if (!tokenIsChar(token, ')'))
				goto invalid;

			/* have a valid HSV entry, convert to RGB */
			HSL_to_RGB(hue, sat, lit, &r, &g, &b);

			/* apply alpha */
			if (alpha > 255)
				a = 255;
			else if (alpha < 0)
				a = 0;
			else
				a = alpha;

		} else {
			goto invalid;
		}

		*result = (a << 24) | (r << 16) | (g << 8) | b;
	}

	*value = COLOR_SET;

	return CSS_OK;

invalid:
	*ctx = orig_ctx;
	return CSS_INVALID;
}
Exemplo n.º 29
0
/**
 * Create a string from a list of IDENT/S tokens
 *
 * \param c          Parsing context
 * \param vector     Vector containing tokens
 * \param ctx        Vector iteration context
 * \param reserved   Callback to determine if an identifier is reserved
 * \param result     Pointer to location to receive resulting string
 * \return CSS_OK on success, appropriate error otherwise.
 *
 * Post condition: \a *ctx is updated with the next token to process
 *                 If the input is invalid, then \a *ctx remains unchanged.
 *
 *                 The resulting string's reference is passed to the caller
 */
css_error css__ident_list_to_string(css_language *c,
		const parserutils_vector *vector, int *ctx,
		bool (*reserved)(css_language *c, const css_token *ident),
		lwc_string **result)
{
	int orig_ctx = *ctx;
	const css_token *token;
	css_error error = CSS_OK;
	parserutils_buffer *buffer;
	parserutils_error perror;
	lwc_string *interned;
	lwc_error lerror;

	perror = parserutils_buffer_create((parserutils_alloc) c->alloc, 
			c->pw, &buffer);
	if (perror != PARSERUTILS_OK)
		return css_error_from_parserutils_error(perror);

	/* We know this token exists, and is an IDENT */
	token = parserutils_vector_iterate(vector, ctx);

	/* Consume all subsequent IDENT or S tokens */	
	while (token != NULL && (token->type == CSS_TOKEN_IDENT ||
			token->type == CSS_TOKEN_S)) {
		if (token->type == CSS_TOKEN_IDENT) {
			/* IDENT -- if reserved, reject style */
			if (reserved != NULL && reserved(c, token)) {
				error = CSS_INVALID;
				goto cleanup;
			}

			perror = parserutils_buffer_append(buffer, 
					(const uint8_t *) lwc_string_data(token->idata), 
					lwc_string_length(token->idata));
		} else {
			/* S */
			perror = parserutils_buffer_append(buffer, 
					(const uint8_t *) " ", 1);
		}

		if (perror != PARSERUTILS_OK) {
			error = css_error_from_parserutils_error(perror);
			goto cleanup;
		}

		token = parserutils_vector_iterate(vector, ctx);
	}

	/* Rewind context by one step if we consumed an unacceptable token */
	if (token != NULL)
		*ctx = *ctx - 1;

	/* Strip trailing whitespace */
	while (buffer->length > 0 && buffer->data[buffer->length - 1] == ' ')
		buffer->length--;

	/* Intern the buffer contents */
	lerror = lwc_intern_string((char *) buffer->data, buffer->length, &interned);
	if (lerror != lwc_error_ok) {
		error = css_error_from_lwc_error(lerror);
		goto cleanup;
	}

	*result = interned;

cleanup:
	parserutils_buffer_destroy(buffer);

	if (error != CSS_OK)
		*ctx = orig_ctx;

	return error;
}
Exemplo n.º 30
0
/* See mimesniff.h for documentation */
nserror mimesniff_compute_effective_type(llcache_handle *handle,
		const uint8_t *data, size_t len, bool sniff_allowed,
		bool image_only, lwc_string **effective_type)
{
#define S(s) { s, SLEN(s) }
	static const struct tt_s {
		const char *data;
		size_t len;
	} text_types[] = {
		S("text/plain"),
		S("text/plain; charset=ISO-8859-1"),
		S("text/plain; charset=iso-8859-1"),
		S("text/plain; charset=UTF-8"),
		{ NULL, 0 }
	};
#undef S

	const char *content_type_header;
	size_t content_type_header_len;
	http_content_type *ct;
	const struct tt_s *tt;
	bool match;
	nserror error;

	content_type_header = 
			llcache_handle_get_header(handle, "Content-Type");
	if (content_type_header == NULL) {
		if (sniff_allowed == false)
			return NSERROR_NOT_FOUND;

		/* No official type => unknown */
		return mimesniff__compute_unknown(data, len, effective_type);
	}

	error = http_parse_content_type(content_type_header, &ct);
	if (error != NSERROR_OK) {
		if (sniff_allowed == false)
			return NSERROR_NOT_FOUND;

		/* Unparseable => unknown */
		return mimesniff__compute_unknown(data, len, effective_type);
	}

	if (sniff_allowed == false) {
		*effective_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return NSERROR_OK;
	}

	if (image_only) {
		lwc_string *official_type;

		if (lwc_string_caseless_isequal(ct->media_type, image_svg, 
				&match) == lwc_error_ok && match) {
			*effective_type = lwc_string_ref(image_svg);
			http_content_type_destroy(ct);
			return NSERROR_OK;
		}

		official_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return mimesniff__compute_image(official_type,
				data, len, effective_type);
	}

	content_type_header_len = strlen(content_type_header);

	/* Look for text types */
	for (tt = text_types; tt->data != NULL; tt++) {
		if (tt->len == content_type_header_len &&
				memcmp(tt->data, content_type_header, 
					content_type_header_len) == 0) {
			http_content_type_destroy(ct);
			return mimesniff__compute_text_or_binary(data, len,
					effective_type);
		}
	}

	/* unknown/unknown, application/unknown, * / * */
	if ((lwc_string_caseless_isequal(ct->media_type, unknown_unknown, 
				&match) == lwc_error_ok && match) ||
			(lwc_string_caseless_isequal(ct->media_type, 
				application_unknown, &match) == lwc_error_ok && 
				match) ||
			(lwc_string_caseless_isequal(ct->media_type, any, 
				&match) == lwc_error_ok && match)) {
		http_content_type_destroy(ct);
		return mimesniff__compute_unknown(data, len, effective_type);
	}

	/* +xml */
	if (lwc_string_length(ct->media_type) > SLEN("+xml") &&
			strncasecmp(lwc_string_data(ct->media_type) + 
				lwc_string_length(ct->media_type) - 
				SLEN("+xml"), 
				"+xml", SLEN("+xml")) == 0) {
		/* Use official type */
		*effective_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return NSERROR_OK;
	}

	/* text/xml, application/xml */
	if ((lwc_string_caseless_isequal(ct->media_type, text_xml, 
				&match) == lwc_error_ok && match) ||
			(lwc_string_caseless_isequal(ct->media_type, 
				application_xml, &match) == lwc_error_ok && 
				match)) {
		/* Use official type */
		*effective_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return NSERROR_OK;
	}
	
	/* Image types */
	if (content_factory_type_from_mime_type(ct->media_type) == 
			CONTENT_IMAGE) {
		lwc_string *official_type = lwc_string_ref(ct->media_type);
		http_content_type_destroy(ct);
		return mimesniff__compute_image(official_type,
				data, len, effective_type);
	}

	/* text/html */
	if ((lwc_string_caseless_isequal(ct->media_type, text_html, 
			&match) == lwc_error_ok && match)) {
		http_content_type_destroy(ct);
		return mimesniff__compute_feed_or_html(data, len,
				effective_type);
	}

	/* Use official type */
	*effective_type = lwc_string_ref(ct->media_type);

	http_content_type_destroy(ct);

	return NSERROR_OK;
}