Work around libcroco < 0.6.2 parsing bug for 'rgba'
To work around a problem where libcroco < 0.6.2 can't handle functions starting with 'r' or 'u', preconvert 'rgba' to 'RGBA' when parsing stylesheets and then check for rgba() case-insensitively. (libcroco is uniformly case-sensitive, though the CSS spec requires that ASCII should be handled case-insensitively.) https://bugzilla.gnome.org/show_bug.cgi?id=597054
This commit is contained in:
parent
fd1e7b2a0f
commit
4ddc1118bb
@ -258,9 +258,7 @@ ensure_properties (StThemeNode *node)
|
|||||||
if (!properties)
|
if (!properties)
|
||||||
properties = g_ptr_array_new ();
|
properties = g_ptr_array_new ();
|
||||||
|
|
||||||
node->inline_properties = cr_declaration_parse_list_from_buf ((const guchar *)node->inline_style,
|
node->inline_properties = _st_theme_parse_declaration_list (node->inline_style);
|
||||||
CR_UTF_8);
|
|
||||||
|
|
||||||
for (cur_decl = node->inline_properties; cur_decl; cur_decl = cur_decl->next)
|
for (cur_decl = node->inline_properties; cur_decl; cur_decl = cur_decl->next)
|
||||||
g_ptr_array_add (properties, cur_decl);
|
g_ptr_array_add (properties, cur_decl);
|
||||||
}
|
}
|
||||||
@ -408,12 +406,21 @@ get_color_from_term (StThemeNode *node,
|
|||||||
/* rgba () colors - a CSS3 addition, are not supported by libcroco,
|
/* rgba () colors - a CSS3 addition, are not supported by libcroco,
|
||||||
* but they are parsed as a "function", so we can emulate the
|
* but they are parsed as a "function", so we can emulate the
|
||||||
* functionality.
|
* functionality.
|
||||||
|
*
|
||||||
|
* libcroco < 0.6.2 has a bug where functions starting with 'r' are
|
||||||
|
* misparsed. We workaround this by pre-converting 'rgba' to 'RGBA'
|
||||||
|
* before parsing the stylesheet. Since libcroco isn't
|
||||||
|
* case-insensitive (a bug), it's fine with functions starting with
|
||||||
|
* 'R'. (In theory, we should be doing a case-insensitive compare
|
||||||
|
* everywhere, not just here, but that doesn't make much sense when
|
||||||
|
* the built-in parsing of libcroco is case-sensitive and things
|
||||||
|
* like 10PX don't work.)
|
||||||
*/
|
*/
|
||||||
else if (term->type == TERM_FUNCTION &&
|
else if (term->type == TERM_FUNCTION &&
|
||||||
term->content.str &&
|
term->content.str &&
|
||||||
term->content.str->stryng &&
|
term->content.str->stryng &&
|
||||||
term->content.str->stryng->str &&
|
term->content.str->stryng->str &&
|
||||||
strcmp (term->content.str->stryng->str, "rgba") == 0)
|
g_ascii_strcasecmp (term->content.str->stryng->str, "rgba") == 0)
|
||||||
{
|
{
|
||||||
return get_color_from_rgba_term (term, color);
|
return get_color_from_rgba_term (term, color);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ char *_st_theme_resolve_url (StTheme *theme,
|
|||||||
CRStyleSheet *base_stylesheet,
|
CRStyleSheet *base_stylesheet,
|
||||||
const char *url);
|
const char *url);
|
||||||
|
|
||||||
|
CRDeclaration *_st_theme_parse_declaration_list (const char *str);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __ST_THEME_PRIVATE_H__ */
|
#endif /* __ST_THEME_PRIVATE_H__ */
|
||||||
|
@ -156,6 +156,92 @@ st_theme_class_init (StThemeClass *klass)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is a workaround for a bug in libcroco < 0.6.2 where
|
||||||
|
* function starting with 'r' (and 'u') are misparsed. We work
|
||||||
|
* around this by exploiting the fact that libcroco is incomformant
|
||||||
|
* with the CSS-spec and case sensitive and pre-convert all
|
||||||
|
* occurrences of rgba to RGBA. Then we make our own parsing
|
||||||
|
* code check for RGBA as well.
|
||||||
|
*/
|
||||||
|
#if LIBCROCO_VERSION_NUMBER < 602
|
||||||
|
static gboolean
|
||||||
|
is_identifier_character (char c)
|
||||||
|
{
|
||||||
|
/* Actual CSS rules allow for unicode > 0x00a1 and escaped
|
||||||
|
* characters, but we'll assume we won't do that in our stylesheets
|
||||||
|
* or at least not next to the string 'rgba'.
|
||||||
|
*/
|
||||||
|
return g_ascii_isalnum(c) || c == '-' || c == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_rgba_RGBA (char *buf)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = strstr (buf, "rgba");
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
/* Check if this looks like a complete token; this is to
|
||||||
|
* avoiding mangling, say, a selector '.rgba-entry' */
|
||||||
|
if (!((p > buf && is_identifier_character (*(p - 1))) ||
|
||||||
|
(is_identifier_character (*(p + 4)))))
|
||||||
|
memcpy(p, "RGBA", 4);
|
||||||
|
p += 4;
|
||||||
|
p = strstr (p, "rgba");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CRStyleSheet *
|
||||||
|
parse_stylesheet (const char *filename)
|
||||||
|
{
|
||||||
|
enum CRStatus status;
|
||||||
|
char *contents;
|
||||||
|
gsize length;
|
||||||
|
GError *error = NULL;
|
||||||
|
CRStyleSheet *stylesheet = NULL;
|
||||||
|
|
||||||
|
if (filename == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!g_file_get_contents (filename, &contents ,&length, &error))
|
||||||
|
{
|
||||||
|
g_warning("Couldn't read stylesheet: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_rgba_RGBA (contents);
|
||||||
|
|
||||||
|
status = cr_om_parser_simply_parse_buf ((const guchar *) contents,
|
||||||
|
length,
|
||||||
|
CR_UTF_8,
|
||||||
|
&stylesheet);
|
||||||
|
|
||||||
|
if (status != CR_OK)
|
||||||
|
g_warning ("Error parsing stylesheet '%s'", filename);
|
||||||
|
|
||||||
|
g_free (contents);
|
||||||
|
|
||||||
|
return stylesheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRDeclaration *
|
||||||
|
_st_theme_parse_declaration_list (const char *str)
|
||||||
|
{
|
||||||
|
char *copy = g_strdup (str);
|
||||||
|
CRDeclaration *result;
|
||||||
|
|
||||||
|
convert_rgba_RGBA (copy);
|
||||||
|
|
||||||
|
result = cr_declaration_parse_list_from_buf ((const guchar *)copy,
|
||||||
|
CR_UTF_8);
|
||||||
|
g_free (copy);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else /* LIBCROCO_VERSION_NUMBER >= 602 */
|
||||||
static CRStyleSheet *
|
static CRStyleSheet *
|
||||||
parse_stylesheet (const char *filename)
|
parse_stylesheet (const char *filename)
|
||||||
{
|
{
|
||||||
@ -178,6 +264,14 @@ parse_stylesheet (const char *filename)
|
|||||||
return stylesheet;
|
return stylesheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRDeclaration *
|
||||||
|
_st_theme_parse_declaration_list (const char *str)
|
||||||
|
{
|
||||||
|
return cr_declaration_parse_list_from_buf ((const guchar *)str,
|
||||||
|
CR_UTF_8);
|
||||||
|
}
|
||||||
|
#endif /* LIBCROCO_VERSION_NUMBER < 602 */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
insert_stylesheet (StTheme *theme,
|
insert_stylesheet (StTheme *theme,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
|
Loading…
Reference in New Issue
Block a user