]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Fix crash with *.po file input
authorDaiki Ueno <ueno@gnu.org>
Thu, 15 Sep 2016 11:57:24 +0000 (13:57 +0200)
committerDaiki Ueno <ueno@gnu.org>
Thu, 15 Sep 2016 12:01:43 +0000 (14:01 +0200)
When xgettext was given two *.po files with the same msgid_plural, it
crashed with double-free.  Problem reported by Davlet Panech in:
http://lists.gnu.org/archive/html/bug-gettext/2016-09/msg00001.html
* gettext-tools/src/po-gram-gen.y: Don't free msgid_pluralform after
calling do_callback_message, assuming that it takes ownership.
* gettext-tools/src/read-catalog.c (default_add_message): Free
msgid_plural after calling message_alloc.
* gettext-tools/tests/xgettext-po-2: New file.
* gettext-tools/tests/Makefile.am (TESTS): Add new test.

gettext-tools/src/po-gram-gen.y
gettext-tools/src/read-catalog.c
gettext-tools/tests/Makefile.am
gettext-tools/tests/xgettext-po-2 [new file with mode: 0755]

index becf5e60756d22d98e1db402e571de391fa4d984..4428e7725e0e822eb5afbf99beaa55f76ca2c528 100644 (file)
@@ -221,14 +221,11 @@ message
                   check_obsolete ($1, $3);
                   check_obsolete ($1, $4);
                   if (!$1.obsolete || pass_obsolete_entries)
-                    {
-                      do_callback_message ($1.ctxt, string2, &$1.pos, $3.string,
-                                           $4.rhs.msgstr, $4.rhs.msgstr_len, &$4.pos,
-                                           $1.prev_ctxt,
-                                           $1.prev_id, $1.prev_id_plural,
-                                           $1.obsolete);
-                      free ($3.string);
-                    }
+                    do_callback_message ($1.ctxt, string2, &$1.pos, $3.string,
+                                         $4.rhs.msgstr, $4.rhs.msgstr_len, &$4.pos,
+                                         $1.prev_ctxt,
+                                         $1.prev_id, $1.prev_id_plural,
+                                         $1.obsolete);
                   else
                     {
                       free_message_intro ($1);
index 571d18e1bd167fa0d8cf095b98873d58a2f2abc3..6af6d20258256d3864e667a8ca3ad28262403f34 100644 (file)
@@ -397,6 +397,8 @@ default_add_message (default_catalog_reader_ty *this,
          appropriate.  */
       mp = message_alloc (msgctxt, msgid, msgid_plural, msgstr, msgstr_len,
                           msgstr_pos);
+      if (msgid_plural != NULL)
+        free (msgid_plural);
       mp->prev_msgctxt = prev_msgctxt;
       mp->prev_msgid = prev_msgid;
       mp->prev_msgid_plural = prev_msgid_plural;
index 23b09b16371dd601a1883262e3c985d3641144ba..0dfb4d867aa6746d7322d180c7066fea3f9f8f35 100644 (file)
@@ -95,7 +95,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
        xgettext-perl-1 xgettext-perl-2 xgettext-perl-3 xgettext-perl-4 \
        xgettext-perl-5 xgettext-perl-6 xgettext-perl-7 xgettext-perl-8 \
        xgettext-php-1 xgettext-php-2 xgettext-php-3 xgettext-php-4 \
-       xgettext-po-1 \
+       xgettext-po-1 xgettext-po-2 \
        xgettext-properties-1 \
        xgettext-python-1 xgettext-python-2 xgettext-python-3 \
        xgettext-python-4 \
diff --git a/gettext-tools/tests/xgettext-po-2 b/gettext-tools/tests/xgettext-po-2
new file mode 100755 (executable)
index 0000000..c4bd9d0
--- /dev/null
@@ -0,0 +1,55 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test PO extractors with multiple input files.
+
+cat <<EOF > xg-po-2-1.po
+msgid "first msgid"
+msgid_plural "first msgid (plural)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "second msgid"
+msgid_plural "second msgid (plural)"
+msgstr[0] ""
+msgstr[1] ""
+EOF
+
+cat <<EOF > xg-po-2-2.po
+msgid "third msgid"
+msgid_plural "third msgid (plural)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "second msgid"
+msgid_plural "second msgid (plural)"
+msgstr[0] ""
+msgstr[1] ""
+EOF
+
+: ${XGETTEXT=xgettext}
+${XGETTEXT} --omit-header xg-po-2-1.po xg-po-2-2.po -o xg-po-2.tmp.po || Exit 1
+LC_ALL=C tr -d '\r' < xg-po-2.tmp.po > xg-po-2.po || Exit 1
+
+cat <<EOF > xg-po-2.ok
+msgid "first msgid"
+msgid_plural "first msgid (plural)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "second msgid"
+msgid_plural "second msgid (plural)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "third msgid"
+msgid_plural "third msgid (plural)"
+msgstr[0] ""
+msgstr[1] ""
+EOF
+
+: ${DIFF=diff}
+${DIFF} xg-po-2.ok xg-po-2.po
+result=$?
+
+exit $result