Changeset 202173 in webkit
- Timestamp:
- Jun 17, 2016, 12:22:02 PM (9 years ago)
- Location:
- trunk/Source/WTF
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r202157 r202173 1 2016-06-17 Mark Lam <mark.lam@apple.com> 2 3 OOM Assertion failure in JSON.stringify. 4 https://bugs.webkit.org/show_bug.cgi?id=158794 5 <rdar://problem/26826254> 6 7 Reviewed by Saam Barati. 8 9 The bug was actually in StringBuilder::appendQuotedJSONString() where it failed 10 to detect an imminent unsigned int overflow. The fix is to use Checked<unsigned> 11 for the needed math, and RELEASE_ASSERT afterwards that we did not overflow. 12 13 I also added more assertions to detect sooner if any there are any problems with 14 StringBuilder's m_buffer or m_length being incorrectly sized. These assertions 15 have been run on the JSC and layout tests without any issue. 16 17 * wtf/text/StringBuilder.cpp: 18 (WTF::StringBuilder::resize): 19 (WTF::StringBuilder::allocateBuffer): 20 (WTF::StringBuilder::allocateBufferUpConvert): 21 (WTF::StringBuilder::reallocateBuffer<LChar>): 22 (WTF::StringBuilder::reallocateBuffer<UChar>): 23 (WTF::StringBuilder::reserveCapacity): 24 (WTF::StringBuilder::appendUninitializedSlow): 25 (WTF::StringBuilder::append): 26 (WTF::StringBuilder::appendQuotedJSONString): 27 * wtf/text/StringBuilder.h: 28 (WTF::StringBuilder::swap): 29 1 30 2016-06-14 Filip Pizlo <fpizlo@apple.com> 2 31 -
trunk/Source/WTF/wtf/text/StringBuilder.cpp
r201782 r202173 1 1 /* 2 * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2010, 2013, 2016 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2012 Google Inc. All rights reserved. 4 4 * … … 81 81 } 82 82 m_length = newSize; 83 ASSERT(m_buffer->length() >= m_length); 83 84 return; 84 85 } … … 104 105 m_buffer = WTFMove(buffer); 105 106 m_string = String(); 107 ASSERT(m_buffer->length() == requiredLength); 106 108 } 107 109 … … 118 120 m_buffer = WTFMove(buffer); 119 121 m_string = String(); 122 ASSERT(m_buffer->length() == requiredLength); 120 123 } 121 124 … … 125 128 { 126 129 ASSERT(m_is8Bit); 130 ASSERT(requiredLength >= m_length); 127 131 // Copy the existing data into a new buffer, set result to point to the end of the existing data. 128 132 auto buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters16); … … 135 139 m_buffer = WTFMove(buffer); 136 140 m_string = String(); 141 ASSERT(m_buffer->length() == requiredLength); 137 142 } 138 143 … … 151 156 else 152 157 allocateBuffer(m_buffer->characters8(), requiredLength); 158 ASSERT(m_buffer->length() == requiredLength); 153 159 } 154 160 … … 166 172 else 167 173 allocateBuffer(m_buffer->characters16(), requiredLength); 174 ASSERT(m_buffer->length() == requiredLength); 168 175 } 169 176 … … 190 197 } 191 198 } 199 ASSERT(!newCapacity || m_buffer->length() >= newCapacity); 192 200 } 193 201 … … 235 243 CharType* result = getBufferCharacters<CharType>() + m_length; 236 244 m_length = requiredLength; 245 ASSERT(m_buffer->length() >= m_length); 237 246 return result; 238 247 } … … 268 277 } 269 278 270 memcpy(m_bufferCharacters16 + m_length, characters, static_cast<size_t>(length) * sizeof(UChar)); 279 memcpy(m_bufferCharacters16 + m_length, characters, static_cast<size_t>(length) * sizeof(UChar)); 271 280 m_length = requiredLength; 272 281 } else 273 282 memcpy(appendUninitialized<UChar>(length), characters, static_cast<size_t>(length) * sizeof(UChar)); 283 ASSERT(m_buffer->length() >= m_length); 274 284 } 275 285 … … 413 423 // The 2 is for the '"' quotes on each end. 414 424 // The 6 is for characters that need to be \uNNNN encoded. 415 size_t maximumCapacityRequired = length() + 2 + string.length() * 6; 416 RELEASE_ASSERT(maximumCapacityRequired < std::numeric_limits<unsigned>::max()); 417 unsigned allocationSize = maximumCapacityRequired; 425 Checked<unsigned> stringLength = string.length(); 426 Checked<unsigned> maximumCapacityRequired = length(); 427 maximumCapacityRequired += 2 + stringLength * 6; 428 unsigned allocationSize = maximumCapacityRequired.unsafeGet(); 418 429 // This max() is here to allow us to allocate sizes between the range [2^31, 2^32 - 2] because roundUpToPowerOfTwo(1<<31 + some int smaller than 1<<31) == 0. 419 430 allocationSize = std::max(allocationSize, roundUpToPowerOfTwo(allocationSize)); … … 423 434 else 424 435 reserveCapacity(allocationSize); 436 ASSERT(m_buffer->length() >= allocationSize); 425 437 426 438 if (is8Bit()) { … … 441 453 m_length = output - m_bufferCharacters16; 442 454 } 455 ASSERT(m_buffer->length() >= m_length); 443 456 } 444 457 -
trunk/Source/WTF/wtf/text/StringBuilder.h
r186279 r202173 1 1 /* 2 * Copyright (C) 2009 , 2010, 2012, 2013Apple Inc. All rights reserved.2 * Copyright (C) 2009-2010, 2012-2013, 2016 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2012 Google Inc. All rights reserved. 4 4 * … … 277 277 std::swap(m_is8Bit, stringBuilder.m_is8Bit); 278 278 std::swap(m_bufferCharacters8, stringBuilder.m_bufferCharacters8); 279 ASSERT(!m_buffer || m_buffer->length() >= m_length); 279 280 } 280 281
Note:
See TracChangeset
for help on using the changeset viewer.