changeset 18313:4ad1eccbe21f

Fix undefined behaviour in gettext.h. * lib/gettext.h (dcpgettext_expr, dcnpgettext_expr): Avoid accessing a pointer's value after the storage it points to has been freed. Reported by Michael Pyne in https://savannah.gnu.org/bugs/?47847. Spotted by Coverity.
author Bruno Haible <bruno@clisp.org>
date Mon, 09 May 2016 09:29:35 +0200
parents ffb17b069818
children 4d47bb4cebc8
files ChangeLog lib/gettext.h
diffstat 2 files changed, 14 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed May 11 08:24:14 2016 -0700
+++ b/ChangeLog	Mon May 09 09:29:35 2016 +0200
@@ -1,3 +1,11 @@
+2016-05-09  Bruno Haible  <bruno@clisp.org>
+
+	Fix undefined behaviour in gettext.h.
+	* lib/gettext.h (dcpgettext_expr, dcnpgettext_expr): Avoid accessing a
+	pointer's value after the storage it points to has been freed.
+	Reported by Michael Pyne in https://savannah.gnu.org/bugs/?47847.
+	Spotted by Coverity.
+
 2016-05-08  Paul Eggert  <eggert@cs.ucla.edu>
 
 	git-version-gen: avoid undefined shift
--- a/lib/gettext.h	Wed May 11 08:24:14 2016 -0700
+++ b/lib/gettext.h	Mon May 09 09:29:35 2016 +0200
@@ -225,15 +225,17 @@
   if (msg_ctxt_id != NULL)
 #endif
     {
+      int found_translation;
       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);
+      found_translation = (translation != msg_ctxt_id);
 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
       if (msg_ctxt_id != buf)
         free (msg_ctxt_id);
 #endif
-      if (translation != msg_ctxt_id)
+      if (found_translation)
         return translation;
     }
   return msgid;
@@ -271,15 +273,17 @@
   if (msg_ctxt_id != NULL)
 #endif
     {
+      int found_translation;
       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);
+      found_translation = !(translation == msg_ctxt_id || translation == msgid_plural);
 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
       if (msg_ctxt_id != buf)
         free (msg_ctxt_id);
 #endif
-      if (!(translation == msg_ctxt_id || translation == msgid_plural))
+      if (found_translation)
         return translation;
     }
   return (n == 1 ? msgid : msgid_plural);