]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: In language Vala, report out-of-range hexadecimal escapes.
authorBruno Haible <bruno@clisp.org>
Sat, 11 Mar 2023 00:21:40 +0000 (01:21 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 14 Mar 2023 01:57:28 +0000 (02:57 +0100)
This avoids a later crash
"Assertion `UNICODE_VALUE (c) >= 0 && UNICODE_VALUE (c) < 0x110000' failed."

* gettext-tools/src/x-vala.c (phase7_getc): When the value of a hexadecimal
escape sequence overflows, warn and use the last value before it overflowed.
* gettext-tools/tests/xgettext-vala-7: New file.
* gettext-tools/tests/Makefile.am (TESTS): Add it.

gettext-tools/src/x-vala.c
gettext-tools/tests/Makefile.am
gettext-tools/tests/xgettext-vala-3 [new file with mode: 0755]

index c26fc96730b0dfadd5de4d6b0c9d38e12489e2ab..20dccb606161b952a5eaf8b3bd69e09ff9f0fe59 100644 (file)
@@ -412,7 +412,7 @@ free_token (token_ty *tp)
 static int
 phase7_getc ()
 {
-  int c, n, j;
+  int c, j;
 
   /* Use phase 1, because phase 2 elides comments.  */
   c = phase1_getc ();
@@ -487,55 +487,82 @@ phase7_getc ()
         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
           break;
         }
-      n = 0;
-      for (;;)
-        {
-          switch (c)
-            {
-            default:
-              phase1_ungetc (c);
-              return n;
+      {
+        int n;
+        bool overflow;
 
-            case '0': case '1': case '2': case '3': case '4':
-            case '5': case '6': case '7': case '8': case '9':
-              n = n * 16 + c - '0';
-              break;
+        n = 0;
+        overflow = false;
 
-            case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-              n = n * 16 + 10 + c - 'A';
-              break;
+        for (;;)
+          {
+            switch (c)
+              {
+              default:
+                phase1_ungetc (c);
+                if (overflow)
+                  {
+                    error_with_progname = false;
+                    error (0, 0, _("%s:%d: warning: hexadecimal escape sequence out of range"),
+                           logical_file_name, line_number);
+                    error_with_progname = true;
+                  }
+                return n;
 
-            case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-              n = n * 16 + 10 + c - 'a';
+              case '0': case '1': case '2': case '3': case '4':
+              case '5': case '6': case '7': case '8': case '9':
+                if (n < 0x100 / 16)
+                  n = n * 16 + c - '0';
+                else
+                  overflow = true;
               break;
-            }
-          c = phase1_getc ();
-        }
-      return n;
+
+              case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+                if (n < 0x100 / 16)
+                  n = n * 16 + 10 + c - 'A';
+                else
+                  overflow = true;
+                break;
+
+              case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+                if (n < 0x100 / 16)
+                  n = n * 16 + 10 + c - 'a';
+                else
+                  overflow = true;
+                break;
+              }
+            c = phase1_getc ();
+          }
+      }
 
     case '0':
-      n = 0;
-      for (j = 0; j < 3; ++j)
-        {
-          n = n * 8 + c - '0';
-          c = phase1_getc ();
-          switch (c)
-            {
-            default:
-              break;
+      {
+        int n;
 
-            case '0': case '1': case '2': case '3':
-            case '4': case '5': case '6': case '7':
-              continue;
-            }
-          break;
-        }
-      phase1_ungetc (c);
-      return n;
+        n = 0;
+        for (j = 0; j < 3; ++j)
+          {
+            n = n * 8 + c - '0';
+            c = phase1_getc ();
+            switch (c)
+              {
+              default:
+                break;
+
+              case '0': case '1': case '2': case '3':
+              case '4': case '5': case '6': case '7':
+                continue;
+              }
+            break;
+          }
+        phase1_ungetc (c);
+        return n;
+      }
 
     case 'u':
       {
         unsigned char buf[8];
+        int n;
 
         n = 0;
         for (j = 0; j < 4; j++)
index dc9802da89919d00c4aaa19b25521d1358a126bf..a9595dfc37a5e1d5ac0a6c903c8c1cc37a936d02 100644 (file)
@@ -155,7 +155,7 @@ TESTS = gettext-1 gettext-2 \
        xgettext-tcl-1 xgettext-tcl-2 xgettext-tcl-3 xgettext-tcl-4 \
        xgettext-tcl-stackovfl-1 xgettext-tcl-stackovfl-2 \
        xgettext-tcl-stackovfl-3 xgettext-tcl-stackovfl-4 \
-       xgettext-vala-1 xgettext-vala-2 \
+       xgettext-vala-1 xgettext-vala-2 xgettext-vala-3 \
        xgettext-vala-stackovfl-1 xgettext-vala-stackovfl-2 \
        xgettext-ycp-1 xgettext-ycp-2 xgettext-ycp-3 xgettext-ycp-4 \
        xgettext-ycp-stackovfl-1 xgettext-ycp-stackovfl-2 \
diff --git a/gettext-tools/tests/xgettext-vala-3 b/gettext-tools/tests/xgettext-vala-3
new file mode 100755 (executable)
index 0000000..ddcae87
--- /dev/null
@@ -0,0 +1,24 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test Vala support: out-of-range hexadecimal escape sequences.
+
+: ${XGETTEXT=xgettext}
+
+cat <<\EOF > xg-vala-3.vala
+_("\x678888");
+EOF
+
+${XGETTEXT} --omit-header --no-location -o xg-vala-3.tmp xg-vala-3.vala || Exit 1
+func_filter_POT_Creation_Date xg-vala-3.tmp xg-vala-3.po
+
+cat <<\EOF > xg-vala-3.ok
+msgid "g"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-vala-3.ok xg-vala-3.po
+result=$?
+
+exit $result