Chromium Code Reviews| Index: src/core/SkString.cpp |
| diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp |
| index a069a7e68a0c5dbc31e788771834db6fb4cbd3a6..3fae07e12a3ac82657f2edfa7629f1332a719d6f 100644 |
| --- a/src/core/SkString.cpp |
| +++ b/src/core/SkString.cpp |
| @@ -189,15 +189,36 @@ const SkString::Rec SkString::gEmptyRec = { 0, 0, 0 }; |
| #define SizeOfRec() (gEmptyRec.data() - (const char*)&gEmptyRec) |
| +static uint32_t trim_size_t_to_u32(size_t value) { |
| + if (sizeof(size_t) > sizeof(uint32_t)) { |
|
bungeman-skia
2013/06/04 15:30:45
I just added SkTFitsIn<T> for exactly this kind of
|
| + if (value > SK_MaxU32) { |
| + value = SK_MaxU32; |
| + } |
| + } |
| + return (uint32_t)value; |
| +} |
| + |
| +static size_t check_add32(size_t base, size_t extra) { |
| + SkASSERT(base <= SK_MaxU32); |
| + if (sizeof(size_t) > sizeof(uint32_t)) { |
| + if (base + extra > SK_MaxU32) { |
| + extra = SK_MaxU32 - base; |
| + } |
| + } |
| + return extra; |
| +} |
| + |
| SkString::Rec* SkString::AllocRec(const char text[], size_t len) { |
| Rec* rec; |
| if (0 == len) { |
| rec = const_cast<Rec*>(&gEmptyRec); |
| } else { |
| + len = trim_size_t_to_u32(len); |
| + |
| // add 1 for terminating 0, then align4 so we can have some slop when growing the string |
| rec = (Rec*)sk_malloc_throw(SizeOfRec() + SkAlign4(len + 1)); |
| - rec->fLength = len; |
| + rec->fLength = SkToU32(len); |
| rec->fRefCnt = 1; |
| if (text) { |
| memcpy(rec->data(), text, len); |
| @@ -356,6 +377,8 @@ void SkString::set(const char text[]) { |
| } |
| void SkString::set(const char text[], size_t len) { |
| + len = trim_size_t_to_u32(len); |
| + |
| if (0 == len) { |
| this->reset(); |
| } else if (1 == fRec->fRefCnt && len <= fRec->fLength) { |
| @@ -366,7 +389,7 @@ void SkString::set(const char text[], size_t len) { |
| memcpy(p, text, len); |
| } |
| p[len] = 0; |
| - fRec->fLength = len; |
| + fRec->fLength = SkToU32(len); |
| } else if (1 == fRec->fRefCnt && (fRec->fLength >> 2) == (len >> 2)) { |
| // we have spare room in the current allocation, so don't alloc a larger one |
| char* p = this->writable_str(); |
| @@ -374,7 +397,7 @@ void SkString::set(const char text[], size_t len) { |
| memcpy(p, text, len); |
| } |
| p[len] = 0; |
| - fRec->fLength = len; |
| + fRec->fLength = SkToU32(len); |
| } else { |
| SkString tmp(text, len); |
| this->swap(tmp); |
| @@ -387,10 +410,12 @@ void SkString::setUTF16(const uint16_t src[]) { |
| while (src[count]) { |
| count += 1; |
| } |
| - setUTF16(src, count); |
| + this->setUTF16(src, count); |
| } |
| void SkString::setUTF16(const uint16_t src[], size_t count) { |
| + count = trim_size_t_to_u32(count); |
| + |
| if (0 == count) { |
| this->reset(); |
| } else if (count <= fRec->fLength) { |
| @@ -424,6 +449,12 @@ void SkString::insert(size_t offset, const char text[], size_t len) { |
| if (offset > length) { |
| offset = length; |
| } |
| + |
| + // Check if length + len exceeds 32bits, we trim len |
| + len = check_add32(length, len); |
| + if (0 == len) { |
| + return; |
| + } |
| /* If we're the only owner, and we have room in our allocation for the insert, |
| do it in place, rather than allocating a new buffer. |
| @@ -444,7 +475,7 @@ void SkString::insert(size_t offset, const char text[], size_t len) { |
| memcpy(dst + offset, text, len); |
| dst[length + len] = 0; |
| - fRec->fLength = length + len; |
| + fRec->fLength = SkToU32(length + len); |
| } else { |
| /* Seems we should use realloc here, since that is safe if it fails |
| (we have the original data), and might be faster than alloc/copy/free. |