summaryrefslogtreecommitdiffstats
path: root/gettext-tools/src
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2014-10-28 16:38:40 +0900
committerDaiki Ueno <ueno@gnu.org>2014-10-30 10:22:29 +0900
commit84044b5fe692b6f32d73ad101327dd219887936b (patch)
treee6e003b0c9d3a7175f9e94955882768c12340f9a /gettext-tools/src
parentdabc935fecfa16774d9930b392ef913a465b714b (diff)
downloadexternal_gettext-84044b5fe692b6f32d73ad101327dd219887936b.zip
external_gettext-84044b5fe692b6f32d73ad101327dd219887936b.tar.gz
external_gettext-84044b5fe692b6f32d73ad101327dd219887936b.tar.bz2
xgettext: Allow plural extraction from a single argument function
The commit 8137d2b4 was a wrong fix since both singular/plural msgids may point to the same address for Qt4 plural forms. This reverts the commit and fix the original double-free problem in the right way. Thanks to Jesper Fehrlund for suggestions. * gettext-tools/src/xgettext.c (arglist_parser_remember_literal): Don't ignore plural argument even if ARGNUM1 equals to ARGNUM2. (arglist_parser_done): Make a copy of best_cp->msgid_plural when passing it to remember_a_message_plural, if it equals to best_cp->msgid. Also move code conversion logic earlier taking into account of the ownership transfer of best_cp->msgid. * gettext-tools/src/xgettext-12: Test a single argument function.
Diffstat (limited to 'gettext-tools/src')
-rw-r--r--gettext-tools/src/ChangeLog14
-rw-r--r--gettext-tools/src/xgettext.c66
2 files changed, 51 insertions, 29 deletions
diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog
index e5ff794..d392ba7 100644
--- a/gettext-tools/src/ChangeLog
+++ b/gettext-tools/src/ChangeLog
@@ -1,5 +1,19 @@
2014-10-28 Daiki Ueno <ueno@gnu.org>
+ xgettext: Allow plural extraction from a single argument function
+ The commit 8137d2b4 was a wrong fix since both singular/plural msgids
+ may point to the same address for Qt4 plural forms. This reverts
+ the commit and fix the original double-free problem in the right
+ way. Thanks to Jesper Fehrlund for suggestions.
+ * xgettext.c (arglist_parser_remember_literal): Don't ignore
+ plural argument even if ARGNUM1 equals to ARGNUM2.
+ (arglist_parser_done): Make a copy of best_cp->msgid_plural when
+ passing it to remember_a_message_plural, if it equals to
+ best_cp->msgid. Also move code conversion logic earlier taking
+ into account of the ownership transfer of best_cp->msgid.
+
+2014-10-28 Daiki Ueno <ueno@gnu.org>
+
xgettext: Fix double-free in singular/plural argument extraction
After commit 6aa7b7ed in 2009, xgettext assumed that ARGNUM1 and
ARGNUM2 of -k are different. That could cause an double-free in
diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c
index a8f3af6..7a4f71a 100644
--- a/gettext-tools/src/xgettext.c
+++ b/gettext-tools/src/xgettext.c
@@ -2791,7 +2791,7 @@ arglist_parser_remember_literal (struct arglist_parser *ap,
/* Mark msgid as done. */
cp->argnum1 = 0;
}
- else if (argnum == cp->argnum2)
+ if (argnum == cp->argnum2)
{
cp->msgid_plural = string;
cp->msgid_plural_escape = type;
@@ -3099,9 +3099,9 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
char *msgid = parser->parse (best_cp->msgid,
&best_cp->msgid_pos,
best_cp->msgid_escape);
- free (best_cp->msgid);
if (best_cp->msgid_plural == best_cp->msgid)
best_cp->msgid_plural = msgid;
+ free (best_cp->msgid);
best_cp->msgid = msgid;
}
else
@@ -3110,26 +3110,7 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
CONVERT_STRING (best_cp->msgid, lc_string);
}
- if (best_cp->msgid_comment != NULL)
- {
- refcounted_string_list_ty *msgid_comment =
- savable_comment_convert_encoding (best_cp->msgid_comment,
- &best_cp->msgid_pos);
- drop_reference (best_cp->msgid_comment);
- best_cp->msgid_comment = msgid_comment;
- }
-
- /* best_cp->msgctxt and best_cp->msgid are already in
- UTF-8. Prevent further conversion in remember_a_message. */
- encoding = xgettext_current_source_encoding;
- xgettext_current_source_encoding = po_charset_utf8;
- mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid,
- msgid_context,
- &best_cp->msgid_pos,
- NULL, best_cp->msgid_comment);
- xgettext_current_source_encoding = encoding;
-
- if (mp != NULL && best_cp->msgid_plural != NULL)
+ if (best_cp->msgid_plural)
{
/* best_cp->msgid_plural may point to best_cp->msgid.
In that case, it is already interpreted and converted. */
@@ -3152,14 +3133,41 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
}
}
- encoding = xgettext_current_source_encoding;
- xgettext_current_source_encoding = po_charset_utf8;
- remember_a_message_plural (mp, best_cp->msgid_plural,
- msgid_plural_context,
- &best_cp->msgid_plural_pos,
- NULL);
- xgettext_current_source_encoding = encoding;
+ /* If best_cp->msgid_plural equals to best_cp->msgid,
+ the ownership will be transferred to
+ remember_a_message before it is passed to
+ remember_a_message_plural.
+
+ Make a copy of the string in that case. */
+ if (best_cp->msgid_plural == best_cp->msgid)
+ best_cp->msgid_plural = xstrdup (best_cp->msgid);
+ }
+
+ if (best_cp->msgid_comment != NULL)
+ {
+ refcounted_string_list_ty *msgid_comment =
+ savable_comment_convert_encoding (best_cp->msgid_comment,
+ &best_cp->msgid_pos);
+ drop_reference (best_cp->msgid_comment);
+ best_cp->msgid_comment = msgid_comment;
}
+
+ /* best_cp->msgctxt, best_cp->msgid, and best_cp->msgid_plural
+ are already in UTF-8. Prevent further conversion in
+ remember_a_message. */
+ encoding = xgettext_current_source_encoding;
+ xgettext_current_source_encoding = po_charset_utf8;
+ mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid,
+ msgid_context,
+ &best_cp->msgid_pos,
+ NULL, best_cp->msgid_comment);
+ if (mp != NULL && best_cp->msgid_plural != NULL)
+ remember_a_message_plural (mp,
+ best_cp->msgid_plural,
+ msgid_plural_context,
+ &best_cp->msgid_plural_pos,
+ NULL);
+ xgettext_current_source_encoding = encoding;
}
if (best_cp->xcomments.nitems > 0)