Mercurial > gnulib
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);