Changeset 76185 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Jan 19, 2011, 5:53:50 PM (14 years ago)
Author:
Darin Adler
Message:

2011-01-18 Darin Adler <Darin Adler>

Reviewed by Geoffrey Garen.

Stack overflow when converting an Error object to string
https://bugs.webkit.org/show_bug.cgi?id=46410

  • fast/js/script-tests/toString-recursion.js: Added.
  • fast/js/toString-recursion-expected.txt: Added.
  • fast/js/toString-recursion.html: Added.

2011-01-18 Darin Adler <Darin Adler>

Reviewed by Geoffrey Garen.

Stack overflow when converting an Error object to string
https://bugs.webkit.org/show_bug.cgi?id=46410

  • Android.mk: Added StringRecursionChecker.cpp and StringRecursionChecker.h.
  • CMakeLists.txt: Ditto.
  • GNUmakefile.am: Ditto.
  • JavaScriptCore.gypi: Ditto.
  • JavaScriptCore.pro: Ditto.
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
  • JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
  • runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncToString): Use StringRecursionChecker instead of the older hand-written code to do the same thing. (JSC::arrayProtoFuncToLocaleString): Ditto. (JSC::arrayProtoFuncJoin): Ditto.
  • runtime/ErrorPrototype.cpp: (JSC::errorProtoFuncToString): Use StringRecursionChecker.
  • runtime/JSGlobalData.h: Renamed arrayVisitedElements to stringRecursionCheckVisitedObjects.
  • runtime/RegExpPrototype.cpp: (JSC::regExpProtoFuncToString): Use StringRecursionChecker.
  • runtime/StringRecursionChecker.cpp: Added.
  • runtime/StringRecursionChecker.h: Added.
Location:
trunk/Source/JavaScriptCore
Files:
2 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/Android.mk

    r75855 r76185  
    152152        runtime/StringObject.cpp \
    153153        runtime/StringPrototype.cpp \
     154        runtime/StringRecursionChecker.cpp \
    154155        runtime/Structure.cpp \
    155156        runtime/StructureChain.cpp \
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r75855 r76185  
    164164    runtime/StringObject.cpp
    165165    runtime/StringPrototype.cpp
     166    runtime/StringRecursionChecker.cpp
    166167    runtime/Structure.cpp
    167168    runtime/StructureChain.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r76180 r76185  
     12011-01-18  Darin Adler  <[email protected]>
     2
     3        Reviewed by Geoffrey Garen.
     4
     5        Stack overflow when converting an Error object to string
     6        https://bugs.webkit.org/show_bug.cgi?id=46410
     7
     8        * Android.mk: Added StringRecursionChecker.cpp and
     9        StringRecursionChecker.h.
     10        * CMakeLists.txt: Ditto.
     11        * GNUmakefile.am: Ditto.
     12        * JavaScriptCore.gypi: Ditto.
     13        * JavaScriptCore.pro: Ditto.
     14        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
     15        * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
     16
     17        * runtime/ArrayPrototype.cpp:
     18        (JSC::arrayProtoFuncToString): Use StringRecursionChecker instead
     19        of the older hand-written code to do the same thing.
     20        (JSC::arrayProtoFuncToLocaleString): Ditto.
     21        (JSC::arrayProtoFuncJoin): Ditto.
     22
     23        * runtime/ErrorPrototype.cpp:
     24        (JSC::errorProtoFuncToString): Use StringRecursionChecker.
     25
     26        * runtime/JSGlobalData.h: Renamed arrayVisitedElements to
     27        stringRecursionCheckVisitedObjects.
     28
     29        * runtime/RegExpPrototype.cpp:
     30        (JSC::regExpProtoFuncToString): Use StringRecursionChecker.
     31
     32        * runtime/StringRecursionChecker.cpp: Added.
     33        * runtime/StringRecursionChecker.h: Added.
     34
    1352011-01-19  Oliver Hunt  <[email protected]>
    236
  • trunk/Source/JavaScriptCore/GNUmakefile.am

    r75855 r76185  
    405405        Source/JavaScriptCore/runtime/StringPrototype.cpp \
    406406        Source/JavaScriptCore/runtime/StringPrototype.h \
     407        Source/JavaScriptCore/runtime/StringRecursionChecker.cpp \
     408        Source/JavaScriptCore/runtime/StringRecursionChecker.h \
    407409        Source/JavaScriptCore/runtime/StructureChain.cpp \
    408410        Source/JavaScriptCore/runtime/StructureChain.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.gypi

    r75855 r76185  
    338338            'runtime/StringPrototype.cpp',
    339339            'runtime/StringPrototype.h',
     340            'runtime/StringRecursionChecker.cpp',
     341            'runtime/StringRecursionChecker.h',
    340342            'runtime/Structure.cpp',
    341343            'runtime/Structure.h',
  • trunk/Source/JavaScriptCore/JavaScriptCore.pro

    r75855 r76185  
    206206    runtime/StringObject.cpp \
    207207    runtime/StringPrototype.cpp \
     208    runtime/StringRecursionChecker.cpp \
    208209    runtime/StructureChain.cpp \
    209210    runtime/Structure.cpp \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r75855 r76185  
    12471247                        </File>
    12481248                        <File
     1249                                RelativePath="..\..\runtime\StringRecursionChecker.cpp"
     1250                                >
     1251                        </File>
     1252                        <File
     1253                                RelativePath="..\..\runtime\StringRecursionChecker.h"
     1254                                >
     1255                        </File>
     1256                        <File
    12491257                                RelativePath="..\..\runtime\Structure.cpp"
    12501258                                >
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r75855 r76185  
    295295                933040040E6A749400786E6A /* SmallStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 93303FEA0E6A72C000786E6A /* SmallStrings.h */; settings = {ATTRIBUTES = (Private, ); }; };
    296296                9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93303FE80E6A72B500786E6A /* SmallStrings.cpp */; };
     297                9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93345A8712D838C400302BE3 /* StringRecursionChecker.cpp */; };
    297298                933F5CDC1269229B0049191E /* NullPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 933F5CDB126922690049191E /* NullPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
    298299                937013480CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 937013470CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp */; settings = {COMPILER_FLAGS = "-Wno-sign-compare"; }; };
     
    926927                93303FE80E6A72B500786E6A /* SmallStrings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmallStrings.cpp; sourceTree = "<group>"; };
    927928                93303FEA0E6A72C000786E6A /* SmallStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallStrings.h; sourceTree = "<group>"; };
     929                93345A8712D838C400302BE3 /* StringRecursionChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringRecursionChecker.cpp; sourceTree = "<group>"; };
     930                93345A8812D838C400302BE3 /* StringRecursionChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringRecursionChecker.h; sourceTree = "<group>"; };
    928931                933A349A038AE7C6008635CE /* Identifier.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Identifier.h; sourceTree = "<group>"; tabWidth = 8; };
    929932                933A349D038AE80F008635CE /* Identifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Identifier.cpp; sourceTree = "<group>"; tabWidth = 8; };
     
    18681871                                BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */,
    18691872                                BC18C3C60E16EE3300B34460 /* StringPrototype.h */,
     1873                                93345A8712D838C400302BE3 /* StringRecursionChecker.cpp */,
     1874                                93345A8812D838C400302BE3 /* StringRecursionChecker.h */,
    18701875                                BCDE3AB00E6C82CF001453A7 /* Structure.cpp */,
    18711876                                BCDE3AB10E6C82CF001453A7 /* Structure.h */,
     
    28742879                                86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
    28752880                                86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
     2881                                9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */,
    28762882                        );
    28772883                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r70703 r76185  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    3  *  Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2003 Peter Kelly ([email protected])
    55 *  Copyright (C) 2006 Alexey Proskuryakov ([email protected])
     
    3333#include "ObjectPrototype.h"
    3434#include "Operations.h"
     35#include "StringRecursionChecker.h"
    3536#include <algorithm>
    3637#include <wtf/Assertions.h>
     
    169170    JSArray* thisObj = asArray(thisValue);
    170171   
    171     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
    172     if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
    173         if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
    174             return throwVMError(exec, createStackOverflowError(exec));
    175     }
    176 
    177     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
    178     if (alreadyVisited)
    179         return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoiding infinite recursion.
     172    StringRecursionChecker checker(exec, thisObj);
     173    if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
     174        return earlyReturnValue;
    180175
    181176    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     
    210205            break;
    211206    }
    212     arrayVisitedElements.remove(thisObj);
    213207    if (!totalSize)
    214208        return JSValue::encode(jsEmptyString(exec));
     
    235229    JSObject* thisObj = asArray(thisValue);
    236230
    237     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
    238     if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
    239         if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
    240             return throwVMError(exec, createStackOverflowError(exec));
    241     }
    242 
    243     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
    244     if (alreadyVisited)
    245         return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion.
     231    StringRecursionChecker checker(exec, thisObj);
     232    if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
     233        return earlyReturnValue;
    246234
    247235    JSStringBuilder strBuffer;
     
    265253        }
    266254    }
    267     arrayVisitedElements.remove(thisObj);
     255
    268256    return JSValue::encode(strBuffer.build(exec));
    269257}
     
    273261    JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
    274262
    275     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
    276     if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
    277         if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
    278             return throwVMError(exec, createStackOverflowError(exec));
    279     }
    280 
    281     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
    282     if (alreadyVisited)
    283         return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion.
     263    StringRecursionChecker checker(exec, thisObj);
     264    if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
     265        return earlyReturnValue;
    284266
    285267    JSStringBuilder strBuffer;
     
    336318            strBuffer.append(element.toString(exec));
    337319    }
    338     arrayVisitedElements.remove(thisObj);
     320
    339321    return JSValue::encode(strBuffer.build(exec));
    340322}
  • trunk/Source/JavaScriptCore/runtime/ErrorPrototype.cpp

    r66616 r76185  
    2727#include "ObjectPrototype.h"
    2828#include "PrototypeFunction.h"
     29#include "StringRecursionChecker.h"
    2930#include "UString.h"
    3031
     
    4849{
    4950    JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
     51
     52    StringRecursionChecker checker(exec, thisObj);
     53    if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
     54        return earlyReturnValue;
     55
    5056    JSValue name = thisObj->get(exec, exec->propertyNames().name);
    5157    JSValue message = thisObj->get(exec, exec->propertyNames().message);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r75443 r76185  
    215215        JSGlobalObject* dynamicGlobalObject;
    216216
    217         HashSet<JSObject*> arrayVisitedElements;
     217        HashSet<JSObject*> stringRecursionCheckVisitedObjects;
    218218
    219219        Stringifier* firstStringifierToMark;
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp

    r75408 r76185  
    3535#include "RegExp.h"
    3636#include "RegExpCache.h"
     37#include "StringRecursionChecker.h"
    3738#include "UStringConcatenate.h"
    3839
     
    112113    }
    113114
     115    RegExpObject* thisObject = asRegExpObject(thisValue);
     116
     117    StringRecursionChecker checker(exec, thisObject);
     118    if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
     119        return earlyReturnValue;
     120
    114121    char postfix[5] = { '/', 0, 0, 0, 0 };
    115122    int index = 1;
    116     if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
     123    if (thisObject->get(exec, exec->propertyNames().global).toBoolean(exec))
    117124        postfix[index++] = 'g';
    118     if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
     125    if (thisObject->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
    119126        postfix[index++] = 'i';
    120     if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
     127    if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean(exec))
    121128        postfix[index] = 'm';
    122     UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
     129    UString source = thisObject->get(exec, exec->propertyNames().source).toString(exec);
    123130    // If source is empty, use "/(?:)/" to avoid colliding with comment syntax
    124131    return JSValue::encode(jsMakeNontrivialString(exec, "/", source.length() ? source : UString("(?:)"), postfix));
Note: See TracChangeset for help on using the changeset viewer.