]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Make literal parser robust against NUL
authorDaiki Ueno <ueno@gnu.org>
Thu, 25 Jun 2015 02:37:39 +0000 (11:37 +0900)
committerDaiki Ueno <ueno@gnu.org>
Thu, 25 Jun 2015 02:37:39 +0000 (11:37 +0900)
* gettext-tools/src/x-c.c (literalstring_parse): Add more NUL checks.
Change the loop invariant so that C always points to the character
previously pointed by P.
Reported by Hanno Boeck in:
<http://savannah.gnu.org/bugs/?45391>.

* gettext-tools/tests/xg-c-21.c (main): New file.
* gettext-tools/tests/xgettext-c-21 (result): New file.
* gettext-tools/tests/Makefile.am (TESTS): Add new test.
(EXTRA_DIST): Add xg-c-21.c.

gettext-tools/src/ChangeLog
gettext-tools/src/x-c.c
gettext-tools/tests/Makefile.am
gettext-tools/tests/xg-c-21.c [new file with mode: 0644]
gettext-tools/tests/xgettext-c-21 [new file with mode: 0755]

index 0b7dbe10a3a52b32a5b09ae3e8535620cae85c18..5b03bac5a7362c764d55c80c678890f1496b8f3e 100644 (file)
@@ -1,3 +1,11 @@
+2015-06-25  Daiki Ueno  <ueno@gnu.org>
+
+       * x-c.c (literalstring_parse): Add more NUL checks.  Change the
+       loop invariant so that C always points to the character previously
+       pointed by P.
+       Reported by Hanno Boeck in:
+       <http://savannah.gnu.org/bugs/?45391>.
+
 2015-06-24  Daiki Ueno  <ueno@gnu.org>
 
        * x-c.c (literalstring_parse): Check if the next character of a
index f6922f8fdc6a0f411dc861b5d4fc4343584d37d5..722f4b6e020eca226e1ba12053f4c71168b01ac2 100644 (file)
@@ -985,13 +985,16 @@ literalstring_parse (const char *string, lex_pos_ty *pos,
                                   logical_file_name,
                                   line_number);
 
-  for (p = string; *p != '\0'; p++)
+  for (p = string; )
     {
-      int c;
+      int c = *p++;
 
-      if (*p != '\\')
+      if (c == '\0')
+        break;
+
+      if (c != '\\')
         {
-          mixed_string_buffer_append_char (bp, *p);
+          mixed_string_buffer_append_char (bp, c);
           continue;
         }
 
@@ -1001,7 +1004,7 @@ literalstring_parse (const char *string, lex_pos_ty *pos,
           continue;
         }
 
-      c = *++p;
+      c = *p++;
       if (c == '\0')
         break;
 
@@ -1043,7 +1046,9 @@ literalstring_parse (const char *string, lex_pos_ty *pos,
             continue;
 
           case 'x':
-            c = *++p;
+            c = *p++;
+            if (c == '\0')
+              break;
             switch (c)
               {
               default:
@@ -1059,26 +1064,26 @@ literalstring_parse (const char *string, lex_pos_ty *pos,
                 {
                   int n;
 
-                  for (n = 0; ; ++p)
+                  for (n = 0; ; c = *p++)
                     {
-                      switch (*p)
+                      switch (c)
                         {
                         default:
                           break;
 
                         case '0': case '1': case '2': case '3': case '4':
                         case '5': case '6': case '7': case '8': case '9':
-                          n = n * 16 + *p - '0';
+                          n = n * 16 + c - '0';
                           continue;
 
                         case 'A': case 'B': case 'C': case 'D': case 'E':
                         case 'F':
-                          n = n * 16 + 10 + *p - 'A';
+                          n = n * 16 + 10 + c - 'A';
                           continue;
 
                         case 'a': case 'b': case 'c': case 'd': case 'e':
                         case 'f':
-                          n = n * 16 + 10 + *p - 'a';
+                          n = n * 16 + 10 + c - 'a';
                           continue;
                         }
                       break;
@@ -1099,7 +1104,7 @@ literalstring_parse (const char *string, lex_pos_ty *pos,
               for (n = 0, j = 0; j < 3; ++j)
                 {
                   n = n * 8 + c - '0';
-                  c = *++p;
+                  c = *p++;
                   switch (c)
                     {
                     default:
@@ -1129,7 +1134,7 @@ literalstring_parse (const char *string, lex_pos_ty *pos,
 
               for (n = 0, j = 0; j < length; j++)
                 {
-                  int c1 = *++p;
+                  int c1 = *p++;
 
                   if (c1 >= '0' && c1 <= '9')
                     n = (n << 4) + (c1 - '0');
index 1526d77d7c06c4552548ebcb6dd07b0e6ab7f2c6..b1026136bd83e4445f0dca681130c5935c461256 100644 (file)
@@ -79,6 +79,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
        xgettext-c-6 xgettext-c-7 xgettext-c-8 xgettext-c-9 xgettext-c-10 \
        xgettext-c-11 xgettext-c-12 xgettext-c-13 xgettext-c-14 xgettext-c-15 \
        xgettext-c-16 xgettext-c-17 xgettext-c-18 xgettext-c-19 xgettext-c-20 \
+       xgettext-c-21 \
        xgettext-csharp-1 xgettext-csharp-2 xgettext-csharp-3 \
        xgettext-csharp-4 xgettext-csharp-5 xgettext-csharp-6 \
        xgettext-csharp-7 xgettext-csharp-8 \
@@ -160,7 +161,7 @@ EXTRA_DIST += init.sh init.cfg $(TESTS) \
        gettext-6-1.po gettext-6-2.po gettext-7.po \
        gettextpo-1.de.po \
        xgettext-1 \
-       xgettext-c-1 \
+       xgettext-c-1 xg-c-21.c \
        common/supplemental/plurals.xml
 
 XGETTEXT = ../src/xgettext
diff --git a/gettext-tools/tests/xg-c-21.c b/gettext-tools/tests/xg-c-21.c
new file mode 100644 (file)
index 0000000..d49b6f0
Binary files /dev/null and b/gettext-tools/tests/xg-c-21.c differ
diff --git a/gettext-tools/tests/xgettext-c-21 b/gettext-tools/tests/xgettext-c-21
new file mode 100755 (executable)
index 0000000..966ae80
--- /dev/null
@@ -0,0 +1,49 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test C support: invalid NUL termination
+
+: ${XGETTEXT=xgettext}
+
+${XGETTEXT} --add-comments --no-location --no-wrap \
+           -o - xg-c-21.c | grep -v 'POT-Creation-Date' > xg-c-21.tmp.po \
+           || exit 1
+LC_ALL=C tr -d '\r' < xg-c-21.tmp.po > xg-c-21.po || exit 1
+
+cat <<\EOF > xg-c-21.ok
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "\n"
+msgstr ""
+
+msgid "\\u"
+msgstr ""
+
+msgid "\\U"
+msgstr ""
+
+msgid "\\u3"
+msgstr ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-c-21.ok xg-c-21.po
+result=$?
+
+exit $result