Ignore:
Timestamp:
Aug 27, 2009, 11:17:36 PM (16 years ago)
Author:
[email protected]
Message:

JSON Stringifier does not follow ES5 spec for handling of Number, String and Boolean objects
https://bugs.webkit.org/show_bug.cgi?id=28797

Reviewed by Maciej Stachowiak

Fixed unwrapBoxedPrimitive to do the right thing, which necessitated a couple of new exception
checks, and corrected the logic in gap to correctly convert Number and String objects.

File:
1 edited

Legend:

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

    r47847 r47857  
    121121// ------------------------------ helper functions --------------------------------
    122122
    123 static inline JSValue unwrapBoxedPrimitive(JSValue value)
     123static inline JSValue unwrapBoxedPrimitive(ExecState* exec, JSValue value)
    124124{
    125125    if (!value.isObject())
    126126        return value;
    127     if (!asObject(value)->inherits(&NumberObject::info) && !asObject(value)->inherits(&StringObject::info) && !asObject(value)->inherits(&BooleanObject::info))
    128         return value;
    129     return static_cast<JSWrapperObject*>(asObject(value))->internalValue();
    130 }
    131 
    132 static inline UString gap(JSValue space)
    133 {
    134     space = unwrapBoxedPrimitive(space);
     127    JSObject* object = asObject(value);
     128    if (object->inherits(&NumberObject::info))
     129        return jsNumber(exec, object->toNumber(exec));
     130    if (object->inherits(&StringObject::info))
     131        return jsString(exec, object->toString(exec));
     132    if (object->inherits(&BooleanObject::info))
     133        return object->toPrimitive(exec);
     134    return value;
     135}
     136
     137static inline UString gap(ExecState* exec, JSValue space)
     138{
     139    const int maxGapLength = 10;
     140    space = unwrapBoxedPrimitive(exec, space);
    135141
    136142    // If the space value is a number, create a gap string with that number of spaces.
    137143    double spaceCount;
    138144    if (space.getNumber(spaceCount)) {
    139         const int maxSpaceCount = 100;
    140145        int count;
    141         if (spaceCount > maxSpaceCount)
    142             count = maxSpaceCount;
     146        if (spaceCount > maxGapLength)
     147            count = maxGapLength;
    143148        else if (!(spaceCount > 0))
    144149            count = 0;
    145150        else
    146151            count = static_cast<int>(spaceCount);
    147         UChar spaces[maxSpaceCount];
     152        UChar spaces[maxGapLength];
    148153        for (int i = 0; i < count; ++i)
    149154            spaces[i] = ' ';
     
    152157
    153158    // If the space value is a string, use it as the gap string, otherwise use no gap string.
    154     return space.getString();
     159    UString spaces = space.getString();
     160    if (spaces.size() > maxGapLength) {
     161        spaces = spaces.substr(0, maxGapLength);
     162    }
     163    return spaces;
    155164}
    156165
     
    188197    , m_arrayReplacerPropertyNames(exec)
    189198    , m_replacerCallType(CallTypeNone)
    190     , m_gap(gap(space))
     199    , m_gap(gap(exec, space))
    191200{
    192201    exec->globalData().firstStringifierToMark = this;
     
    204213                break;
    205214
    206             if (name.isObject()) {
    207                 if (!asObject(name)->inherits(&NumberObject::info) && !asObject(name)->inherits(&StringObject::info))
    208                     continue;
    209                 name = static_cast<JSWrapperObject*>(asObject(name))->internalValue();
    210             }
    211 
    212215            UString propertyName;
    213216            if (name.getString(propertyName)) {
     
    222225            }
    223226
    224             if (exec->hadException())
    225                 return;
     227            if (name.isObject()) {
     228                if (!asObject(name)->inherits(&NumberObject::info) && !asObject(name)->inherits(&StringObject::info))
     229                    continue;
     230                propertyName = name.toString(exec);
     231                if (exec->hadException())
     232                    break;
     233                m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName));
     234            }
    226235        }
    227236        return;
     
    370379    }
    371380
    372     value = unwrapBoxedPrimitive(value);
     381    value = unwrapBoxedPrimitive(m_exec, value);
     382
     383    if (m_exec->hadException())
     384        return StringifyFailed;
    373385
    374386    if (value.isBoolean()) {
Note: See TracChangeset for help on using the changeset viewer.