diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-02-26 13:20:47 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-02-26 13:27:58 +0300 |
commit | 88facb8876c3943685e0b69a5c2f01d77f136252 (patch) | |
tree | 876fa335a0c3e7c89a836b41a35200ccf4d54f2c /source | |
parent | 8197f0bb645f73f41071daaccf205a7583e695f5 (diff) |
Fix potential buffer overflow in `BLI_strncpy_wchar_as_utf8()`.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/intern/string_utf8.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index f2930044204..c93c3cf628c 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -249,6 +249,7 @@ char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxncpy) { const size_t maxlen = maxncpy - 1; + const size_t maxlen_secured = ((int)maxlen - 6) < 0 ? 0 : maxlen - 6; /* 6 is max utf8 length of an unicode char. */ size_t len = 0; BLI_assert(maxncpy != 0); @@ -257,10 +258,23 @@ size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict memset(dst, 0xff, sizeof(*dst) * maxncpy); #endif - while (*src && len < maxlen) { /* XXX can still run over the buffer because utf8 size isn't known :| */ + while (*src && len < maxlen_secured) { len += BLI_str_utf8_from_unicode((unsigned int)*src++, dst + len); } + /* We have to be more careful for the last six bytes, to avoid buffer overflow in case utf8-encoded char + * would be too long for our dst buffer. */ + while (*src) { + char t[6]; + size_t l = BLI_str_utf8_from_unicode((unsigned int)*src++, t); + BLI_assert(l <= 6); + if (len + l >= maxlen) { + break; + } + memcpy(dst + len, t, l); + len += l; + } + dst[len] = '\0'; return len; |