diff options
author | Sergio Giro <sgiro@google.com> | 2016-07-14 12:49:59 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-07-14 12:49:59 +0000 |
commit | d0ad14ca211dcc2be12a685c7ea8ab071c03b80a (patch) | |
tree | 2338a91503f2377f73db3b1bcabbf2ef14a28637 /libutils/Unicode.cpp | |
parent | ddd00519683ced100cd982f4a429055e28d2a5bc (diff) | |
parent | 5fce0542b6b822b6a79fc4cb0e12db1eb7d41f6c (diff) |
DO NOT MERGE libutils/Unicode.cpp: Correct length computation and add checks for utf16->utf8
am: 5fce0542b6
Change-Id: I348b457decce08d6d08819a16d618b0bc194aa91
Diffstat (limited to 'libutils/Unicode.cpp')
-rw-r--r-- | libutils/Unicode.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp index a66e3bbbb..ef1057f89 100644 --- a/libutils/Unicode.cpp +++ b/libutils/Unicode.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <log/log.h> #include <utils/Unicode.h> #include <stddef.h> @@ -188,7 +189,7 @@ ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len) return ret; } -void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst) +void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_len) { if (src == NULL || src_len == 0 || dst == NULL) { return; @@ -199,9 +200,12 @@ void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst) char *cur = dst; while (cur_utf32 < end_utf32) { size_t len = utf32_codepoint_utf8_length(*cur_utf32); + LOG_ALWAYS_FATAL_IF(dst_len < len, "%zu < %zu", dst_len, len); utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len); cur += len; + dst_len -= len; } + LOG_ALWAYS_FATAL_IF(dst_len < 1, "dst_len < 1: %zu < 1", dst_len); *cur = '\0'; } @@ -330,7 +334,7 @@ int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2 : 0); } -void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst) +void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_len) { if (src == NULL || src_len == 0 || dst == NULL) { return; @@ -350,9 +354,12 @@ void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst) utf32 = (char32_t) *cur_utf16++; } const size_t len = utf32_codepoint_utf8_length(utf32); + LOG_ALWAYS_FATAL_IF(dst_len < len, "%zu < %zu", dst_len, len); utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len); cur += len; + dst_len -= len; } + LOG_ALWAYS_FATAL_IF(dst_len < 1, "%zu < 1", dst_len); *cur = '\0'; } @@ -413,10 +420,10 @@ ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len) const char16_t* const end = src + src_len; while (src < end) { if ((*src & 0xFC00) == 0xD800 && (src + 1) < end - && (*++src & 0xFC00) == 0xDC00) { + && (*(src + 1) & 0xFC00) == 0xDC00) { // surrogate pairs are always 4 bytes. ret += 4; - src++; + src += 2; } else { ret += utf32_codepoint_utf8_length((char32_t) *src++); } |