csstokenizer: Handle backslash at end of document
authorBenjamin Otte <otte@redhat.com>
Tue, 7 May 2019 06:56:28 +0000 (08:56 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 7 May 2019 22:58:52 +0000 (00:58 +0200)
Testcases included.

gtk/css/gtkcsstokenizer.c
testsuite/css/parser/backslash-eof-is-identifier.css [new file with mode: 0644]
testsuite/css/parser/backslash-eof-is-identifier.errors [new file with mode: 0644]
testsuite/css/parser/backslash-eof-is-identifier.ref.css [new file with mode: 0644]
testsuite/css/parser/backslash.css [new file with mode: 0644]
testsuite/css/parser/backslash.errors [new file with mode: 0644]
testsuite/css/parser/backslash.ref.css [new file with mode: 0644]
testsuite/css/parser/meson.build

index 90e781c04fe053e71705cb6014a01da5329e73a4..c9a38566574b6ee636f05fae8e56f5526179d37b 100644 (file)
@@ -633,13 +633,6 @@ is_name (char c)
       || c == '-';
 }
 
-static gboolean
-is_valid_escape (char c1, char c2)
-{
-  return c1 == '\\'
-      && !is_newline (c2);
-}
-
 static gboolean
 is_non_printable (char c)
 {
@@ -650,6 +643,25 @@ is_non_printable (char c)
       || c == 0x7F;
 }
 
+static gboolean
+is_valid_escape (const char *data,
+                 const char *end)
+{
+  switch (end - data)
+    {
+      default:
+        if (is_newline (data[1]))
+          return FALSE;
+        G_GNUC_FALLTHROUGH;
+
+      case 1:
+        return data[0] == '\\';
+
+      case 0:
+        return FALSE;
+    }
+}
+
 static inline gsize
 gtk_css_tokenizer_remaining (GtkCssTokenizer *tokenizer)
 {
@@ -659,15 +671,7 @@ gtk_css_tokenizer_remaining (GtkCssTokenizer *tokenizer)
 static gboolean
 gtk_css_tokenizer_has_valid_escape (GtkCssTokenizer *tokenizer)
 {
-  switch (gtk_css_tokenizer_remaining (tokenizer))
-    {
-      case 0:
-        return FALSE;
-      case 1:
-        return *tokenizer->data == '\\';
-      default:
-        return is_valid_escape (tokenizer->data[0], tokenizer->data[1]);
-    }
+  return is_valid_escape (tokenizer->data, tokenizer->end);
 }
 
 static gboolean
@@ -814,7 +818,11 @@ gtk_css_tokenizer_read_escape (GtkCssTokenizer *tokenizer)
 
   if (i == 0)
     {
-      value = g_utf8_get_char_validated (tokenizer->data, gtk_css_tokenizer_remaining (tokenizer));
+      gsize remaining = gtk_css_tokenizer_remaining (tokenizer);
+      if (remaining == 0)
+        return 0xFFFD;
+
+      value = g_utf8_get_char_validated (tokenizer->data, remaining);
       if (value == (gunichar) -1 || value == (gunichar) -2)
         value = 0;
 
diff --git a/testsuite/css/parser/backslash-eof-is-identifier.css b/testsuite/css/parser/backslash-eof-is-identifier.css
new file mode 100644 (file)
index 0000000..feebb23
--- /dev/null
@@ -0,0 +1,2 @@
+a {
+  animation-name: \
\ No newline at end of file
diff --git a/testsuite/css/parser/backslash-eof-is-identifier.errors b/testsuite/css/parser/backslash-eof-is-identifier.errors
new file mode 100644 (file)
index 0000000..898da05
--- /dev/null
@@ -0,0 +1,2 @@
+backslash-eof-is-identifier.css:2:3-20: error: GTK_CSS_PARSER_WARNING_SYNTAX
+backslash-eof-is-identifier.css:1:3-2:20: error: GTK_CSS_PARSER_WARNING_SYNTAX
diff --git a/testsuite/css/parser/backslash-eof-is-identifier.ref.css b/testsuite/css/parser/backslash-eof-is-identifier.ref.css
new file mode 100644 (file)
index 0000000..2a9f652
--- /dev/null
@@ -0,0 +1,3 @@
+a {
+  animation-name: �;
+}
diff --git a/testsuite/css/parser/backslash.css b/testsuite/css/parser/backslash.css
new file mode 100644 (file)
index 0000000..b7d5379
--- /dev/null
@@ -0,0 +1 @@
+\
\ No newline at end of file
diff --git a/testsuite/css/parser/backslash.errors b/testsuite/css/parser/backslash.errors
new file mode 100644 (file)
index 0000000..129660f
--- /dev/null
@@ -0,0 +1 @@
+backslash.css:1:2: error: GTK_CSS_PARSER_ERROR_SYNTAX
diff --git a/testsuite/css/parser/backslash.ref.css b/testsuite/css/parser/backslash.ref.css
new file mode 100644 (file)
index 0000000..e69de29
index 4ab3fbb305bdb03dca5c72e0b9da0ea4652f6b1d..4aa29a49c37b0ef24f2a913db9f7a96c3e887ee6 100644 (file)
@@ -160,6 +160,12 @@ test_data = [
   'background-shorthand-single.ref.css',
   'background-size.css',
   'background-size.ref.css',
+  'backslash.css',
+  'backslash.errors',
+  'backslash.ref.css',
+  'backslash-eof-is-identifier.css',
+  'backslash-eof-is-identifier.errors',
+  'backslash-eof-is-identifier.ref.css',
   'border-color.css',
   'border-color-currentcolor.css',
   'border-color-currentcolor.ref.css',