bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2] gettext-h: avoid undefined behavior


From: Daiki Ueno
Subject: [PATCH v2] gettext-h: avoid undefined behavior
Date: Mon, 9 May 2016 12:01:48 +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..c5c0294 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);
+      result = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+      if (!(result == msg_ctxt_id || result == msgid_plural))
+        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 || translation == msgid_plural))
-        return translation;
-    }
-  return (n == 1 ? msgid : msgid_plural);
+  return translation;
 }
 
 #endif /* _LIBGETTEXT_H */
-- 
2.5.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]