summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2021-06-08 15:08:22 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2021-06-08 15:08:22 +0900
commit6d19a40a8a23d9aa5d61ace247a5fea1bd103995 (patch)
tree7da06ef7c080f5cf11446728a5ea0ca6fce33587 /src
parentf9b50dafc5d3cc9d463be17b1d9e66817d4cb41c (diff)
downloadlibgpg-error-6d19a40a8a23d9aa5d61ace247a5fea1bd103995.tar.gz
core: Avoid truncation of error message in the middle of a character.
* configure.ac (AM_LANGINFO_CODESET): Add. * src/strerror.c (_gpg_strerror_r): Check the boundary of character. -- GnuPG-bug-id: 5048 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'src')
-rw-r--r--src/strerror.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/strerror.c b/src/strerror.c
index 4cce17f..fb1bebf 100644
--- a/src/strerror.c
+++ b/src/strerror.c
@@ -32,6 +32,10 @@
#include "gettext.h"
#include "err-codes.h"
+#if defined(ENABLE_NLS) && defined(HAVE_LANGINFO_CODESET)
+#include <langinfo.h>
+#endif
+
/* Return a pointer to a string containing a description of the error
code in the error value ERR. This function is not thread-safe. */
const char *
@@ -169,9 +173,30 @@ _gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen)
errstr = dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]);
errstr_len = strlen (errstr) + 1;
cpy_len = errstr_len < buflen ? errstr_len : buflen;
+#if defined(ENABLE_NLS) && defined(HAVE_LANGINFO_CODESET)
+ /* Avoid truncation in the middle of "character" boundary. */
+ if (buflen && errstr_len > buflen
+ && ((unsigned char)errstr[cpy_len-1] & 0xC0) == 0x80
+ && !strcasecmp (nl_langinfo (CODESET), "UTF-8"))
+ {
+ /* Go back to the boundary */
+ for (; cpy_len; cpy_len--)
+ if (((unsigned char)errstr[cpy_len-1] & 0xC0) != 0x80)
+ break;
+ memcpy (buf, errstr, cpy_len);
+ memset (buf+cpy_len, 0, buflen - cpy_len);
+ }
+ else
+ {
+ memcpy (buf, errstr, cpy_len);
+ if (buflen)
+ buf[buflen - 1] = '\0';
+ }
+#else
memcpy (buf, errstr, cpy_len);
if (buflen)
buf[buflen - 1] = '\0';
+#endif
return cpy_len == errstr_len ? 0 : ERANGE;
}