Code: ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
{
 if (src == NULL || src_len == 0) {
 return -1;
 }

 size_t ret = 0;

     const char16_t* const end = src + src_len;
     while (src < end) {
         if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
                && (*++src & 0xFC00) == 0xDC00) {
             ret += 4;
            src++;
         } else {
             ret += utf32_codepoint_utf8_length((char32_t) *src++);
         }
 }
 return ret;
}

Commit Message: libutils/Unicode.cpp: Correct length computation and add checks for utf16->utf8

Inconsistent behaviour between utf16_to_utf8 and utf16_to_utf8_length
is causing a heap overflow.

Correcting the length computation and adding bound checks to the
conversion functions.

Test: ran libutils_tests
Bug: 29250543
Change-Id: I6115e3357141ed245c63c6eb25fc0fd0a9a7a2bb
(cherry picked from commit c4966a363e46d2e1074d1a365e232af0dcedd6a1)

CWE ID: CWE-119
ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
{
 if (src == NULL || src_len == 0) {
 return -1;
 }

 size_t ret = 0;

     const char16_t* const end = src + src_len;
     while (src < end) {
         if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
                && (*(src + 1) & 0xFC00) == 0xDC00) {
             ret += 4;
            src += 2;
         } else {
             ret += utf32_codepoint_utf8_length((char32_t) *src++);
         }
 }
 return ret;
}
