aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkUtils.cpp
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-12-21 13:34:24 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-12-21 21:06:44 +0000
commit889d521d8715f4934accb630097bc09bf7ad1a32 (patch)
tree6e41a72f078156cf8e5338ebd5165df191ab97fd /src/core/SkUtils.cpp
parent8957a1058e3937bc22192837d2fe87c4a8a047b7 (diff)
validate text during deserialization
Bug: 796473 Change-Id: I7b6a6c698a5b53c915ef6564852fa51ce7410a3e Reviewed-on: https://skia-review.googlesource.com/88520 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Hal Canary <halcanary@google.com>
Diffstat (limited to 'src/core/SkUtils.cpp')
-rw-r--r--src/core/SkUtils.cpp51
1 files changed, 43 insertions, 8 deletions
diff --git a/src/core/SkUtils.cpp b/src/core/SkUtils.cpp
index 1eb2a7df43..6eceef52c1 100644
--- a/src/core/SkUtils.cpp
+++ b/src/core/SkUtils.cpp
@@ -82,8 +82,12 @@ int SkUTF8_CountUnichars(const char utf8[]) {
}
// SAFE: returns -1 if invalid UTF-8
-int SkUTF8_CountUnicharsWithError(const char utf8[], size_t byteLength) {
- SkASSERT(utf8 || 0 == byteLength);
+int SkUTF8_CountUnichars(const void* text, size_t byteLength) {
+ SkASSERT(text);
+ const char* utf8 = static_cast<const char*>(text);
+ if (byteLength == 0) {
+ return 0;
+ }
int count = 0;
const char* stop = utf8 + byteLength;
@@ -91,8 +95,8 @@ int SkUTF8_CountUnicharsWithError(const char utf8[], size_t byteLength) {
while (utf8 < stop) {
int type = utf8_byte_type(*(const uint8_t*)utf8);
SkASSERT(type >= -1 && type <= 4);
- if (!utf8_type_is_valid_leading_byte(type) ||
- utf8 + type > stop) { // Sequence extends beyond end.
+ if (!utf8_type_is_valid_leading_byte(type) || utf8 + type > stop) {
+ // Sequence extends beyond end.
return -1;
}
while(type-- > 1) {
@@ -254,16 +258,26 @@ int SkUTF16_CountUnichars(const uint16_t src[]) {
return count;
}
-int SkUTF16_CountUnichars(const uint16_t src[], int numberOf16BitValues) {
- SkASSERT(src);
+// returns -1 on error
+int SkUTF16_CountUnichars(const void* text, size_t byteLength) {
+ SkASSERT(text);
+ if (byteLength == 0) {
+ return 0;
+ }
+ if (!SkIsAlign2(intptr_t(text)) || !SkIsAlign2(byteLength)) {
+ return -1;
+ }
- const uint16_t* stop = src + numberOf16BitValues;
+ const uint16_t* src = static_cast<const uint16_t*>(text);
+ const uint16_t* stop = src + (byteLength >> 1);
int count = 0;
while (src < stop) {
unsigned c = *src++;
SkASSERT(!SkUTF16_IsLowSurrogate(c));
if (SkUTF16_IsHighSurrogate(c)) {
- SkASSERT(src < stop);
+ if (src >= stop) {
+ return -1;
+ }
c = *src++;
SkASSERT(SkUTF16_IsLowSurrogate(c));
}
@@ -361,3 +375,24 @@ const char SkHexadecimalDigits::gUpper[16] =
const char SkHexadecimalDigits::gLower[16] =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+// returns -1 on error
+int SkUTF32_CountUnichars(const void* text, size_t byteLength) {
+ if (byteLength == 0) {
+ return 0;
+ }
+ if (!SkIsAlign4(intptr_t(text)) || !SkIsAlign4(byteLength)) {
+ return -1;
+ }
+ const uint32_t kInvalidUnicharMask = 0xFF000000; // unichar fits in 24 bits
+ const uint32_t* ptr = static_cast<const uint32_t*>(text);
+ const uint32_t* stop = ptr + (byteLength >> 2);
+ while (ptr < stop) {
+ if (*ptr & kInvalidUnicharMask) {
+ return -1;
+ }
+ ptr += 1;
+ }
+ return SkToInt(byteLength >> 2);
+}
+