>From c7d9b146a201074b9559e9d5020333d680a1a5ec Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 9 May 2016 09:29:35 +0200 Subject: [PATCH] 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. --- ChangeLog | 8 ++++++++ lib/gettext.h | 8 ++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe747e5..a8ba38e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-05-09 Bruno Haible + + 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 git-version-gen: avoid undefined shift diff --git a/lib/gettext.h b/lib/gettext.h index 3acc6a6..d26b8b4 100644 --- a/lib/gettext.h +++ b/lib/gettext.h @@ -225,15 +225,17 @@ dcpgettext_expr (const char *domain, 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 @@ dcnpgettext_expr (const char *domain, 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); -- 2.6.4