[gtk] csstokenizer: Handle backslash at end of document



commit bc7972dfa7043408c719a8a63645439efe4f71ce
Author: Benjamin Otte <otte redhat com>
Date:   Tue May 7 08:56:28 2019 +0200

    csstokenizer: Handle backslash at end of document
    
    Testcases included.

 gtk/css/gtkcsstokenizer.c                          | 42 +++++++++++++---------
 .../css/parser/backslash-eof-is-identifier.css     |  2 ++
 .../css/parser/backslash-eof-is-identifier.errors  |  2 ++
 .../css/parser/backslash-eof-is-identifier.ref.css |  3 ++
 testsuite/css/parser/backslash.css                 |  1 +
 testsuite/css/parser/backslash.errors              |  1 +
 testsuite/css/parser/backslash.ref.css             |  0
 testsuite/css/parser/meson.build                   |  6 ++++
 8 files changed, 40 insertions(+), 17 deletions(-)
---
diff --git a/gtk/css/gtkcsstokenizer.c b/gtk/css/gtkcsstokenizer.c
index 90e781c04f..c9a3856657 100644
--- a/gtk/css/gtkcsstokenizer.c
+++ b/gtk/css/gtkcsstokenizer.c
@@ -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
index 0000000000..feebb23c4d
--- /dev/null
+++ b/testsuite/css/parser/backslash-eof-is-identifier.css
@@ -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
index 0000000000..898da0551f
--- /dev/null
+++ b/testsuite/css/parser/backslash-eof-is-identifier.errors
@@ -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
index 0000000000..2a9f65267d
--- /dev/null
+++ b/testsuite/css/parser/backslash-eof-is-identifier.ref.css
@@ -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
index 0000000000..b7d5379f9e
--- /dev/null
+++ b/testsuite/css/parser/backslash.css
@@ -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
index 0000000000..129660ffca
--- /dev/null
+++ b/testsuite/css/parser/backslash.errors
@@ -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
index 0000000000..e69de29bb2
diff --git a/testsuite/css/parser/meson.build b/testsuite/css/parser/meson.build
index 4ab3fbb305..4aa29a49c3 100644
--- a/testsuite/css/parser/meson.build
+++ b/testsuite/css/parser/meson.build
@@ -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',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]