Ignore:
Timestamp:
Apr 28, 2009, 10:56:18 PM (16 years ago)
Author:
[email protected]
Message:

A little more hardening for UString

Reviewed by Maciej Stachowiak.

Revised fix for <rdar://problem/5861045> in r42644.

  • runtime/UString.cpp: (JSC::newCapacityWithOverflowCheck): Added. (JSC::concatenate): Used newCapacityWithOverflowCheck(). (JSC::UString::append): Ditto.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/UString.cpp

    r42644 r42988  
    492492}
    493493
     494static ALWAYS_INLINE int newCapacityWithOverflowCheck(const int currentCapacity, const int extendLength, const bool plusOne = false)
     495{
     496    ASSERT_WITH_MESSAGE(extendLength >= 0, "extendedLength = %d", extendLength);
     497
     498    const int plusLength = plusOne ? 1 : 0;
     499    if (currentCapacity > std::numeric_limits<int>::max() - extendLength - plusLength)
     500        CRASH();
     501
     502    return currentCapacity + extendLength + plusLength;
     503}
     504
    494505static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const UChar* tData, int tSize)
    495506{
     
    511522    } else if (rep == base && !base->isShared()) {
    512523        // this is direct and has refcount of 1 (so we can just alter it directly)
    513         int newCapacity = thisOffset + length;
    514         if (newCapacity < thisOffset)
    515             CRASH();
    516         if (!expandCapacity(rep.get(), newCapacity))
     524        if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
    517525            rep = &UString::Rep::null();
    518526        if (rep->data()) {
     
    523531    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
    524532        // this reaches the end of the buffer - extend it if it's long enough to append to
    525         int newCapacity = thisOffset + length;
    526         if (newCapacity < thisOffset)
    527             CRASH();
    528         if (!expandCapacity(rep.get(), newCapacity))
     533        if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
    529534            rep = &UString::Rep::null();
    530535        if (rep->data()) {
     
    571576    } else if (rep == base && !base->isShared()) {
    572577        // this is direct and has refcount of 1 (so we can just alter it directly)
    573         int newCapacity = thisOffset + length;
    574         if (newCapacity < thisOffset)
    575             CRASH();
    576         expandCapacity(rep.get(), newCapacity);
     578        expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
    577579        UChar* d = rep->data();
    578580        if (d) {
     
    584586    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
    585587        // this string reaches the end of the buffer - extend it
    586         int newCapacity = thisOffset + length;
    587         if (newCapacity < thisOffset)
    588             CRASH();
    589         expandCapacity(rep.get(), newCapacity);
     588        expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
    590589        UChar* d = rep->data();
    591590        if (d) {
     
    651650       
    652651        UString x(a);
    653         int capacity = aOffset + length;
    654         if (capacity < aOffset)
    655             CRASH();
    656         x.expandCapacity(capacity);
     652        x.expandCapacity(newCapacityWithOverflowCheck(aOffset, length));
    657653        if (!a->data() || !x.data())
    658654            return 0;
     
    10041000    } else if (m_rep == base && !base->isShared()) {
    10051001        // this is direct and has refcount of 1 (so we can just alter it directly)
    1006         int newCapacity = thisOffset + length;
    1007         if (newCapacity < thisOffset)
    1008             CRASH();
    1009         expandCapacity(newCapacity);
     1002        expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
    10101003        if (data()) {
    10111004            copyChars(m_rep->data() + thisSize, t.data(), tSize);
     
    10151008    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
    10161009        // this reaches the end of the buffer - extend it if it's long enough to append to
    1017         int newCapacity = thisOffset + length;
    1018         if (newCapacity < thisOffset)
    1019             CRASH();
    1020         expandCapacity(newCapacity);
     1010        expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
    10211011        if (data()) {
    10221012            copyChars(m_rep->data() + thisSize, t.data(), tSize);
     
    10771067    } else if (m_rep == base && !base->isShared()) {
    10781068        // this is direct and has refcount of 1 (so we can just alter it directly)
    1079         int newCapacity = thisOffset + length + 1;
    1080         if (newCapacity < thisOffset)
    1081             CRASH();
    1082         expandCapacity(newCapacity);
     1069        expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
    10831070        UChar* d = m_rep->data();
    10841071        if (d) {
     
    10891076    } else if (thisOffset + length == base->usedCapacity && length >= minShareSize) {
    10901077        // this reaches the end of the string - extend it and share
    1091         int newCapacity = thisOffset + length + 1;
    1092         if (newCapacity < thisOffset)
    1093             CRASH();
    1094         expandCapacity(newCapacity);
     1078        expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
    10951079        UChar* d = m_rep->data();
    10961080        if (d) {
Note: See TracChangeset for help on using the changeset viewer.