diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2021-06-08 15:08:22 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2021-06-08 15:08:22 +0900 |
commit | 6d19a40a8a23d9aa5d61ace247a5fea1bd103995 (patch) | |
tree | 7da06ef7c080f5cf11446728a5ea0ca6fce33587 /src | |
parent | f9b50dafc5d3cc9d463be17b1d9e66817d4cb41c (diff) | |
download | libgpg-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.c | 25 |
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; } |