simplify size check in string
b/72956754 Bug: skia: Change-Id: I50627d9c7fe84630c496f8829608cde875512da0 Reviewed-on: https://skia-review.googlesource.com/107304 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
parent
0be01ccecb
commit
33f38b05fb
@ -48,6 +48,13 @@ public:
|
||||
return add(x, alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
template <typename T> T castTo(size_t value) {
|
||||
if (!SkTFitsIn<T>(value)) {
|
||||
fOK = false;
|
||||
}
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
// These saturate to their results
|
||||
static size_t Add(size_t x, size_t y);
|
||||
static size_t Mul(size_t x, size_t y);
|
||||
|
@ -5,8 +5,8 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#include "SkAtomics.h"
|
||||
#include "SkSafeMath.h"
|
||||
#include "SkString.h"
|
||||
#include "SkUtils.h"
|
||||
#include <stdarg.h>
|
||||
@ -224,13 +224,18 @@ sk_sp<SkString::Rec> SkString::Rec::Make(const char text[], size_t len) {
|
||||
return sk_sp<SkString::Rec>(const_cast<Rec*>(&gEmptyRec));
|
||||
}
|
||||
|
||||
len = trim_size_t_to_u32(len);
|
||||
// add 1 for terminating 0, then align4 so we can have some slop when growing the string
|
||||
const size_t actualLength = SizeOfRec() + SkAlign4(len + 1);
|
||||
SkASSERT_RELEASE(len < actualLength); // Check for overflow.
|
||||
SkSafeMath safe;
|
||||
// We store a 32bit version of the length
|
||||
uint32_t stringLen = safe.castTo<uint32_t>(len);
|
||||
// Add SizeOfRec() for our overhead and 1 for null-termination
|
||||
size_t allocationSize = safe.add(len, SizeOfRec() + sizeof(char));
|
||||
// Align up to a multiple of 4
|
||||
allocationSize = safe.alignUp(allocationSize, 4);
|
||||
|
||||
void* storage = ::operator new (actualLength);
|
||||
sk_sp<Rec> rec(new (storage) Rec(SkToU32(len), 1));
|
||||
SkASSERT_RELEASE(safe.ok());
|
||||
|
||||
void* storage = ::operator new (allocationSize);
|
||||
sk_sp<Rec> rec(new (storage) Rec(stringLen, 1));
|
||||
if (text) {
|
||||
memcpy(rec->data(), text, len);
|
||||
}
|
||||
|
@ -304,3 +304,24 @@ DEF_TEST(String_Threaded, r) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the string allocate doesn't internally overflow any calculations, and accidentally
|
||||
// let us create a string with a requested length longer than we can manage.
|
||||
DEF_TEST(String_huge, r) {
|
||||
// start testing slightly below max 32
|
||||
size_t size = SK_MaxU32 - 16;
|
||||
// See where we crash, and manually check that its at the right point.
|
||||
//
|
||||
// To test, change the false to true
|
||||
while (false) {
|
||||
// On a 64bit build, this should crash when size == 1 << 32, since we can't store
|
||||
// that length in the string's header (which has a u32 slot for the length).
|
||||
//
|
||||
// On a 32bit build, this should crash the first time around, since we can't allocate
|
||||
// anywhere near this amount.
|
||||
//
|
||||
SkString str(size);
|
||||
size += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user