summaryrefslogtreecommitdiff
path: root/libutils/Unicode.cpp
diff options
context:
space:
mode:
authorSergio Giro <sgiro@google.com>2016-07-13 12:58:09 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-07-13 12:58:09 +0000
commitc06d338ad707d21586f273ab3d8e025c1d984611 (patch)
tree29142fd2593a0ed2ff31fea028eab91ae0c26b13 /libutils/Unicode.cpp
parentd837e743812132ca21fcbcfcbdddd377aded3e92 (diff)
parent80473d5d3310204c80a05be469b9fa371866c21c (diff)
Revert \\\\\\"libutils/Unicode.cpp: Correct length computation and add checks for utf16->utf8\\\\\\" am: 311002936e am: ddd0051968 am: b218b2d34d am: 605de74373 am: 37826f5613
am: 80473d5d33 Change-Id: Ia5cb6e89924e69df568d633472656dd4b0c12a76
Diffstat (limited to 'libutils/Unicode.cpp')
-rw-r--r--libutils/Unicode.cpp57
1 files changed, 4 insertions, 53 deletions
diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp
index 5272aec89..fb876c91f 100644
--- a/libutils/Unicode.cpp
+++ b/libutils/Unicode.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <log/log.h>
#include <utils/Unicode.h>
#include <stddef.h>
@@ -183,7 +182,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, size_t dst_len)
+void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst)
{
if (src == NULL || src_len == 0 || dst == NULL) {
return;
@@ -194,12 +193,9 @@ void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_le
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';
}
@@ -328,7 +324,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, size_t dst_len)
+void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst)
{
if (src == NULL || src_len == 0 || dst == NULL) {
return;
@@ -349,12 +345,9 @@ void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_le
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';
}
@@ -405,35 +398,8 @@ ssize_t utf8_length(const char *src)
return ret;
}
-// DO NOT USE. Flawed version, kept only to check whether the flaw is being exploited.
-static ssize_t flawed_utf16_to_utf8_length(const char16_t *src, size_t src_len)
-{
- if (src == NULL || src_len == 0) {
- return 47;
- }
-
- size_t ret = 0;
- const char16_t* const end = src + src_len;
- while (src < end) {
- if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
- // Shouldn't increment src here as to be consistent with utf16_to_utf8
- && (*++src & 0xFC00) == 0xDC00) {
- // surrogate pairs are always 4 bytes.
- ret += 4;
- // Should increment src here by two.
- src++;
- } else {
- ret += utf32_codepoint_utf8_length((char32_t) *src++);
- }
- }
- return ret;
-}
-
ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
{
- // Keep the original pointer to compute the flawed length. Unused if we remove logging.
- const char16_t *orig_src = src;
-
if (src == NULL || src_len == 0) {
return -1;
}
@@ -442,29 +408,14 @@ 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 + 1) & 0xFC00) == 0xDC00) {
+ && (*++src & 0xFC00) == 0xDC00) {
// surrogate pairs are always 4 bytes.
ret += 4;
- src += 2;
+ src++;
} else {
ret += utf32_codepoint_utf8_length((char32_t) *src++);
}
}
- // Log whether b/29250543 is being exploited. It seems reasonable to assume that
- // at least 5 bytes would be needed for an exploit. A single misplaced character might lead to
- // a difference of 4, so this would rule out many false positives.
- long ret_difference = ret - flawed_utf16_to_utf8_length(orig_src, src_len);
- if (ret_difference >= 5) {
- // Log the difference between new and old calculation. A high number, or equal numbers
- // appearing frequently, would be indicative of an attack.
- const unsigned long max_logged_string_length = 20;
- char logged_string[max_logged_string_length + 1];
- unsigned long logged_string_length =
- snprintf(logged_string, max_logged_string_length, "%ld", ret_difference);
- logged_string[logged_string_length] = '\0';
- android_errorWriteWithInfoLog(0x534e4554, "29250543", -1 /* int_uid */,
- logged_string, logged_string_length);
- }
return ret;
}