Changeset 55035 in webkit
- Timestamp:
- Feb 19, 2010 3:36:09 PM (14 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r55027 r55035 1 2010-02-19 Gavin Barraclough <barraclough@apple.com> 2 3 Reviewed by Oliver Hunt. 4 5 JSString::getIndex() calls value() to resolve the string value (is a rope) 6 to a UString, then passes the result to jsSingleCharacterSubstring without 7 checking for an exception. In case of out-of-memory the returned UString 8 is null(), which may result in an out-of-buounds substring being created. 9 This is bad. 10 11 Simple fix is to be able to get an index from a rope without resolving to 12 UString. This may be a useful optimization in some test cases. 13 14 The same bug exists in some other methods is JSString, these can be fixed 15 by changing them to call getIndex(). 16 17 * runtime/JSString.cpp: 18 (JSC::JSString::resolveRope): 19 (JSC::JSString::getStringPropertyDescriptor): 20 * runtime/JSString.h: 21 (JSC::jsSingleCharacterSubstring): 22 (JSC::JSString::getIndex): 23 (JSC::jsSingleCharacterString): 24 (JSC::JSString::getStringPropertySlot): 25 * runtime/UStringImpl.cpp: 26 (JSC::singleCharacterSubstring): 27 * runtime/UStringImpl.h: 28 (JSC::UStringImpl::singleCharacterSubstring): 29 1 30 2010-02-19 Oliver Hunt <oliver@apple.com> 2 31 -
trunk/JavaScriptCore/runtime/JSString.cpp
r54843 r55035 51 51 m_value = newImpl; 52 52 else { 53 for (unsigned i = 0; i < m_fiberCount; ++i) {54 m_other.m_fibers[i]->deref();55 m_other.m_fibers[i] = 0;56 }57 m_fiberCount = 0;58 ASSERT(!isRope());59 ASSERT(m_value == UString());60 53 throwOutOfMemoryError(exec); 61 54 return; … … 188 181 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); 189 182 if (isStrictUInt32 && i < m_length) { 190 descriptor.setDescriptor( jsSingleCharacterSubstring(exec, value(exec), i), DontDelete | ReadOnly);183 descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly); 191 184 return true; 192 185 } -
trunk/JavaScriptCore/runtime/JSString.h
r54925 r55035 42 42 JSString* jsSingleCharacterString(JSGlobalData*, UChar); 43 43 JSString* jsSingleCharacterString(ExecState*, UChar); 44 JSString* jsSingleCharacterSubstring(JSGlobalData*, const UString&, unsigned offset);45 44 JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset); 46 45 JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length); … … 366 365 } 367 366 368 inline JSString* jsSingleCharacterSubstring(JSGlobalData* globalData, const UString& s, unsigned offset) 369 { 367 inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) 368 { 369 JSGlobalData* globalData = &exec->globalData(); 370 370 371 ASSERT(offset < static_cast<unsigned>(s.size())); 371 372 UChar c = s.data()[offset]; … … 392 393 { 393 394 ASSERT(canGetIndex(i)); 394 return jsSingleCharacterSubstring(&exec->globalData(), value(exec), i); 395 if (!isRope()) 396 return jsSingleCharacterSubstring(exec, m_value, i); 397 398 if (i < m_other.m_fibers[0]->length()) 399 return jsString(exec, singleCharacterSubstring(m_other.m_fibers[0], i)); 400 i -= m_other.m_fibers[0]->length(); 401 402 ASSERT(m_fiberCount >= 2); 403 if (i < m_other.m_fibers[1]->length()) 404 return jsString(exec, singleCharacterSubstring(m_other.m_fibers[1], i)); 405 i -= m_other.m_fibers[1]->length(); 406 407 ASSERT(m_fiberCount == 3); 408 ASSERT(i < m_other.m_fibers[2]->length()); 409 return jsString(exec, singleCharacterSubstring(m_other.m_fibers[2], i)); 395 410 } 396 411 … … 446 461 inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); } 447 462 inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); } 448 inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) { return jsSingleCharacterSubstring(&exec->globalData(), s, offset); }449 463 inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); } 450 464 inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); } … … 462 476 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); 463 477 if (isStrictUInt32 && i < m_length) { 464 slot.setValue( jsSingleCharacterSubstring(exec, value(exec), i));478 slot.setValue(getIndex(exec, i)); 465 479 return true; 466 480 } … … 472 486 { 473 487 if (propertyName < m_length) { 474 slot.setValue( jsSingleCharacterSubstring(exec, value(exec), propertyName));488 slot.setValue(getIndex(exec, propertyName)); 475 489 return true; 476 490 } -
trunk/JavaScriptCore/runtime/UStringImpl.cpp
r54843 r55035 150 150 } 151 151 152 PassRefPtr<UStringImpl> singleCharacterSubstring(UStringOrRopeImpl* impl, unsigned index) 153 { 154 top: 155 if (impl->isRope()) { 156 URopeImpl* rope = static_cast<URopeImpl*>(impl); 157 for (unsigned i = 0; i < rope->m_fiberCount; ++i) { 158 UStringOrRopeImpl* currentFiber = rope->fibers(i); 159 unsigned fiberLength = currentFiber->length(); 160 if (index < fiberLength) { 161 impl = currentFiber; 162 goto top; 163 } 164 index -= fiberLength; 165 } 166 CRASH(); 167 } 168 169 return static_cast<UStringImpl*>(impl)->singleCharacterSubstring(index); 170 } 171 152 172 } // namespace JSC -
trunk/JavaScriptCore/runtime/UStringImpl.h
r54870 r55035 213 213 } 214 214 215 PassRefPtr<UStringImpl> singleCharacterSubstring(unsigned index) { ASSERT(index < length()); return create(this, index, 1); } 216 215 217 private: 216 218 // For SmallStringStorage, which allocates an array and uses an in-place new. … … 343 345 344 346 friend class UStringOrRopeImpl; 347 friend PassRefPtr<UStringImpl> singleCharacterSubstring(UStringOrRopeImpl* ropeoid, unsigned index); 345 348 }; 346 349 … … 355 358 bool equal(const UStringImpl*, const UStringImpl*); 356 359 360 PassRefPtr<UStringImpl> singleCharacterSubstring(UStringOrRopeImpl* ropeoid, unsigned index); 361 357 362 } 358 363
Note: See TracChangeset
for help on using the changeset viewer.