[gnome-shell] Work around libcroco < 0.6.2 parsing bug for 'rgba'
- From: Owen Taylor <otaylor src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-shell] Work around libcroco < 0.6.2 parsing bug for 'rgba'
- Date: Mon, 5 Oct 2009 21:08:30 +0000 (UTC)
commit 4ddc1118bb745a489f3b37c4d2475131ba4c36ae
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Mon Oct 5 10:10:23 2009 -0400
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
src/st/st-theme-node.c | 15 +++++--
src/st/st-theme-private.h | 2 +
src/st/st-theme.c | 94 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 4 deletions(-)
---
diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c
index 0b48e47..d0e9135 100644
--- a/src/st/st-theme-node.c
+++ b/src/st/st-theme-node.c
@@ -258,9 +258,7 @@ ensure_properties (StThemeNode *node)
if (!properties)
properties = g_ptr_array_new ();
- node->inline_properties = cr_declaration_parse_list_from_buf ((const guchar *)node->inline_style,
- CR_UTF_8);
-
+ node->inline_properties = _st_theme_parse_declaration_list (node->inline_style);
for (cur_decl = node->inline_properties; cur_decl; cur_decl = cur_decl->next)
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,
* but they are parsed as a "function", so we can emulate the
* 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 &&
term->content.str &&
term->content.str->stryng &&
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);
}
diff --git a/src/st/st-theme-private.h b/src/st/st-theme-private.h
index a307b08..92e87e8 100644
--- a/src/st/st-theme-private.h
+++ b/src/st/st-theme-private.h
@@ -15,6 +15,8 @@ char *_st_theme_resolve_url (StTheme *theme,
CRStyleSheet *base_stylesheet,
const char *url);
+CRDeclaration *_st_theme_parse_declaration_list (const char *str);
+
G_END_DECLS
#endif /* __ST_THEME_PRIVATE_H__ */
diff --git a/src/st/st-theme.c b/src/st/st-theme.c
index 420f1fa..9447832 100644
--- a/src/st/st-theme.c
+++ b/src/st/st-theme.c
@@ -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 *
parse_stylesheet (const char *filename)
{
@@ -178,6 +264,14 @@ parse_stylesheet (const char *filename)
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
insert_stylesheet (StTheme *theme,
const char *filename,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]