]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: In language JavaScript, avoid a crash at an XML comment, CDATA, or PI.
authorBruno Haible <bruno@clisp.org>
Sun, 12 Mar 2023 23:10:47 +0000 (00:10 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 14 Mar 2023 01:57:28 +0000 (02:57 +0100)
* gettext-tools/src/x-javascript.c (phase5_scan_xml_markup): Return int instead
of bool.
(phase5_get): Ignore XML markup parsed by phase5_scan_xml_markup.
* gettext-tools/tests/xgettext-javascript-9: New file.
* gettext-tools/tests/xgettext-javascript-10: New file.
* gettext-tools/tests/xgettext-javascript-11: New file.
* gettext-tools/tests/Makefile.am (TESTS): Add them.

gettext-tools/src/x-javascript.c
gettext-tools/tests/Makefile.am
gettext-tools/tests/xgettext-javascript-10 [new file with mode: 0755]
gettext-tools/tests/xgettext-javascript-11 [new file with mode: 0755]
gettext-tools/tests/xgettext-javascript-9 [new file with mode: 0755]

index 4836a46118ed398d50106f179378acc728af8ce1..98710394d0d677ac19656075055041c90069eb71 100644 (file)
@@ -1019,19 +1019,25 @@ new_brace_depth_level (void)
 static int xml_element_depth;
 static bool inside_embedded_js_in_xml;
 
-static bool
+/* Parses some XML markup.
+   Returns 0 for an XML comment,
+           1 for a CDATA,
+           2 for an XML Processing Instruction,
+   or -1 when none of them was recognized.  */
+static int
 phase5_scan_xml_markup (token_ty *tp)
 {
   struct
-  {
-    const char *start;
-    const char *end;
-  } markers[] =
-      {
-        { "!--", "--" },
-        { "![CDATA[", "]]" },
-        { "?", "?" }
-      };
+    {
+      const char *start;
+      const char *end;
+    }
+  markers[] =
+    {
+      { "!--", "--" },
+      { "![CDATA[", "]]" },
+      { "?", "?" }
+    };
   int i;
 
   for (i = 0; i < SIZEOF (markers); i++)
@@ -1105,13 +1111,13 @@ phase5_scan_xml_markup (token_ty *tp)
                            logical_file_name, line_number,
                            end);
                     error_with_progname = true;
-                    return false;
+                    return -1;
                   }
-                return true;
+                return i;
               }
           }
     }
-  return false;
+  return -1;
 
  eof:
   error_with_progname = false;
@@ -1119,7 +1125,7 @@ phase5_scan_xml_markup (token_ty *tp)
          _("%s:%d: warning: unterminated XML markup"),
          logical_file_name, line_number);
   error_with_progname = true;
-  return false;
+  return -1;
 }
 
 static void
@@ -1350,12 +1356,25 @@ phase5_get (token_ty *tp)
                 || (!inside_embedded_js_in_xml
                     && ! is_after_expression ()))
               {
-                /* Comments, PI, or CDATA.  */
-                if (phase5_scan_xml_markup (tp))
-                  /* BUG: *tp is not filled in here!  */
-                  return;
-                c = phase2_getc ();
+                /* Recognize XML markup: XML comment, CDATA, Processing
+                   Instruction.  */
+                int xml_markup_type = phase5_scan_xml_markup (tp);
+                if (xml_markup_type >= 0)
+                  {
+                    /* Ignore them all, since they are not part of JSX.
+                       But warn about CDATA.  */
+                    if (xml_markup_type == 1)
+                      {
+                        error_with_progname = false;
+                        error (0, 0,
+                               _("%s:%d: warning: ignoring CDATA section"),
+                               logical_file_name, line_number);
+                        error_with_progname = true;
+                      }
+                    continue;
+                  }
 
+                c = phase2_getc ();
                 if (c == '/')
                   {
                     /* Closing tag.  */
index 83e5ef17b81e134661a4adcf1825b0f9b60a8a09..6ca580bd7f723d806ece9c10b7a2f02396c673cb 100644 (file)
@@ -113,7 +113,8 @@ TESTS = gettext-1 gettext-2 \
        xgettext-java-stackovfl-3 xgettext-java-stackovfl-4 \
        xgettext-javascript-1 xgettext-javascript-2 xgettext-javascript-3 \
        xgettext-javascript-4 xgettext-javascript-5 xgettext-javascript-6 \
-       xgettext-javascript-7 xgettext-javascript-8 \
+       xgettext-javascript-7 xgettext-javascript-8 xgettext-javascript-9 \
+       xgettext-javascript-10 xgettext-javascript-11 \
        xgettext-javascript-stackovfl-1 xgettext-javascript-stackovfl-2 \
        xgettext-javascript-stackovfl-3 xgettext-javascript-stackovfl-4 \
        xgettext-javascript-stackovfl-5 xgettext-javascript-stackovfl-6 \
diff --git a/gettext-tools/tests/xgettext-javascript-10 b/gettext-tools/tests/xgettext-javascript-10
new file mode 100755 (executable)
index 0000000..f276fac
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test JavaScript support: CDATA section.
+
+cat <<\EOF > xg-js-10a.js
+<![CDATA[]]>
+EOF
+
+cat <<\EOF > xg-js-10b.js
+<![CDATA[A CDATA section can contain all sort of unescaped characters: >, <, /, etc.]]>
+EOF
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --no-location -d xg-js-10.tmp xg-js-10a.js 2>xg-js-10.err
+result=$?
+cat xg-js-10.err
+test $result = 0 || Exit 1
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --no-location -d xg-js-10.tmp xg-js-10b.js 2>xg-js-10.err
+result=$?
+cat xg-js-10.err
+test $result = 0 || Exit 1
+
+exit 0
diff --git a/gettext-tools/tests/xgettext-javascript-11 b/gettext-tools/tests/xgettext-javascript-11
new file mode 100755 (executable)
index 0000000..f2787d5
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test JavaScript support: XML Processing Instruction.
+
+cat <<\EOF > xg-js-11a.js
+<??>
+EOF
+
+cat <<\EOF > xg-js-11b.js
+<?xml version="1.0" encoding="UTF-8"?>
+EOF
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --no-location -d xg-js-11.tmp xg-js-11a.js 2>xg-js-11.err
+result=$?
+cat xg-js-11.err
+test $result = 0 || Exit 1
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --no-location -d xg-js-11.tmp xg-js-11b.js 2>xg-js-11.err
+result=$?
+cat xg-js-11.err
+test $result = 0 || Exit 1
+
+exit 0
diff --git a/gettext-tools/tests/xgettext-javascript-9 b/gettext-tools/tests/xgettext-javascript-9
new file mode 100755 (executable)
index 0000000..e9b121d
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test JavaScript support: XML comment.
+
+cat <<\EOF > xg-js-9a.js
+<!---->
+EOF
+
+cat <<\EOF > xg-js-9b.js
+<!-- This is an XML comment. -->
+EOF
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --no-location -d xg-js-9.tmp xg-js-9a.js 2>xg-js-9.err
+result=$?
+cat xg-js-9.err
+test $result = 0 || Exit 1
+
+: ${XGETTEXT=xgettext}
+LANGUAGE= LC_ALL=C ${XGETTEXT} --no-location -d xg-js-9.tmp xg-js-9b.js 2>xg-js-9.err
+result=$?
+cat xg-js-9.err
+test $result = 0 || Exit 1
+
+exit 0