[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] gettext-h: avoid undefined behavior
From: |
Daiki Ueno |
Subject: |
[PATCH] gettext-h: avoid undefined behavior |
Date: |
Mon, 9 May 2016 11:35:24 +0900 |
Problem reported by Michael Pyne in:
https://savannah.gnu.org/bugs/?47847
* lib/gettext.h (dcpgettext_expr, dcnpgettext_expr): Delay freeing
allocated buffer until all pointers to it are no longer used.
Spotted by Coverity.
---
ChangeLog | 9 +++++++++
lib/gettext.h | 34 ++++++++++++++++++----------------
2 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index fe747e5..41453d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-05-09 Daiki Ueno <address@hidden>
+
+ gettext-h: avoid undefined behavior
+ Problem reported by Michael Pyne in:
+ https://savannah.gnu.org/bugs/?47847
+ * lib/gettext.h (dcpgettext_expr, dcnpgettext_expr): Delay freeing
+ allocated buffer until all pointers to it are no longer used.
+ Spotted by Coverity.
+
2016-05-08 Paul Eggert <address@hidden>
git-version-gen: avoid undefined shift
diff --git a/lib/gettext.h b/lib/gettext.h
index 3acc6a6..d0fac57 100644
--- a/lib/gettext.h
+++ b/lib/gettext.h
@@ -213,7 +213,7 @@ dcpgettext_expr (const char *domain,
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
- const char *translation;
+ const char *translation = msgid;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
@@ -225,18 +225,19 @@ dcpgettext_expr (const char *domain,
if (msg_ctxt_id != NULL)
#endif
{
+ const char *result;
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
- translation = dcgettext (domain, msg_ctxt_id, category);
+ result = dcgettext (domain, msg_ctxt_id, category);
+ if (result != msg_ctxt_id)
+ translation = result;
+ }
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
- if (msg_ctxt_id != buf)
- free (msg_ctxt_id);
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
#endif
- if (translation != msg_ctxt_id)
- return translation;
- }
- return msgid;
+ return translation;
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
@@ -259,7 +260,7 @@ dcnpgettext_expr (const char *domain,
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
- const char *translation;
+ const char *translation = (n == 1 ? msgid : msgid_plural);
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
@@ -271,18 +272,19 @@ dcnpgettext_expr (const char *domain,
if (msg_ctxt_id != NULL)
#endif
{
+ const char *result;
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
- translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n,
category);
-#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
- if (msg_ctxt_id != buf)
- free (msg_ctxt_id);
-#endif
+ result = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
if (!(translation == msg_ctxt_id || translation == msgid_plural))
- return translation;
+ translation = result;
}
- return (n == 1 ? msgid : msgid_plural);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
+#endif
+ return translation;
}
#endif /* _LIBGETTEXT_H */
--
2.5.5
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] gettext-h: avoid undefined behavior,
Daiki Ueno <=