[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198
darin at apple.com
darin at apple.com
Sun Feb 20 23:20:53 UTC 2011
The following commit has been merged in the webkit-1.3 branch:
commit 4cd37c3172b7c1be2de934c34b55640264e40d3f
Author: darin at apple.com <darin at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Jan 20 01:53:50 2011 +0000
2011-01-18 Darin Adler <darin at apple.com>
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 at apple.com>
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.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76185 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d07a6b4..b327f1c 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2011-01-18 Darin Adler <darin at apple.com>
+
+ 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-19 Oliver Hunt <oliver at apple.com>
Reviewed by Gavin Barraclough.
diff --git a/LayoutTests/fast/js/script-tests/toString-recursion.js b/LayoutTests/fast/js/script-tests/toString-recursion.js
new file mode 100644
index 0000000..42b3a7e
--- /dev/null
+++ b/LayoutTests/fast/js/script-tests/toString-recursion.js
@@ -0,0 +1,14 @@
+description(
+"This test checks that toString() does not have a problem when an object has itself as a property."
+);
+
+// Array (elements)
+shouldBe("var array = []; array[0] = array; array + ''", "''");
+
+// Error (name, message)
+shouldBe("var error = new Error; error.name = error; error.message = error; error + ''", "': '");
+
+// RegExp (source)
+shouldBe("var regexp = /a/; regexp.source = regexp; regexp + ''", "'/a/'");
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/js/toString-recursion-expected.txt b/LayoutTests/fast/js/toString-recursion-expected.txt
new file mode 100644
index 0000000..8a00e9a
--- /dev/null
+++ b/LayoutTests/fast/js/toString-recursion-expected.txt
@@ -0,0 +1,12 @@
+This test checks that toString() does not have a problem when an object has itself as a property.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS var array = []; array[0] = array; array + '' is ''
+PASS var error = new Error; error.name = error; error.message = error; error + '' is ': '
+PASS var regexp = /a/; regexp.source = regexp; regexp + '' is '/a/'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/toString-recursion.html b/LayoutTests/fast/js/toString-recursion.html
new file mode 100644
index 0000000..df349c9
--- /dev/null
+++ b/LayoutTests/fast/js/toString-recursion.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/toString-recursion.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/Source/JavaScriptCore/Android.mk b/Source/JavaScriptCore/Android.mk
index 3c01aa0..80c8b61 100644
--- a/Source/JavaScriptCore/Android.mk
+++ b/Source/JavaScriptCore/Android.mk
@@ -151,6 +151,7 @@ LOCAL_SRC_FILES := \
runtime/StringConstructor.cpp \
runtime/StringObject.cpp \
runtime/StringPrototype.cpp \
+ runtime/StringRecursionChecker.cpp \
runtime/Structure.cpp \
runtime/StructureChain.cpp \
runtime/TimeoutChecker.cpp \
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 29de8a7..674d272 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -163,6 +163,7 @@ SET(JavaScriptCore_SOURCES
runtime/StringConstructor.cpp
runtime/StringObject.cpp
runtime/StringPrototype.cpp
+ runtime/StringRecursionChecker.cpp
runtime/Structure.cpp
runtime/StructureChain.cpp
runtime/TimeoutChecker.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index b2184e5..a1f5f73 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,37 @@
+2011-01-18 Darin Adler <darin at apple.com>
+
+ 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.
+
2011-01-19 Oliver Hunt <oliver at apple.com>
Reviewed by Gavin Barraclough.
diff --git a/Source/JavaScriptCore/GNUmakefile.am b/Source/JavaScriptCore/GNUmakefile.am
index 4c8d204..7272471 100644
--- a/Source/JavaScriptCore/GNUmakefile.am
+++ b/Source/JavaScriptCore/GNUmakefile.am
@@ -404,6 +404,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h \
Source/JavaScriptCore/runtime/StringPrototype.cpp \
Source/JavaScriptCore/runtime/StringPrototype.h \
+ Source/JavaScriptCore/runtime/StringRecursionChecker.cpp \
+ Source/JavaScriptCore/runtime/StringRecursionChecker.h \
Source/JavaScriptCore/runtime/StructureChain.cpp \
Source/JavaScriptCore/runtime/StructureChain.h \
Source/JavaScriptCore/runtime/Structure.cpp \
diff --git a/Source/JavaScriptCore/JavaScriptCore.gypi b/Source/JavaScriptCore/JavaScriptCore.gypi
index a08b439..6ca18a0 100644
--- a/Source/JavaScriptCore/JavaScriptCore.gypi
+++ b/Source/JavaScriptCore/JavaScriptCore.gypi
@@ -337,6 +337,8 @@
'runtime/StringObjectThatMasqueradesAsUndefined.h',
'runtime/StringPrototype.cpp',
'runtime/StringPrototype.h',
+ 'runtime/StringRecursionChecker.cpp',
+ 'runtime/StringRecursionChecker.h',
'runtime/Structure.cpp',
'runtime/Structure.h',
'runtime/StructureChain.cpp',
diff --git a/Source/JavaScriptCore/JavaScriptCore.pro b/Source/JavaScriptCore/JavaScriptCore.pro
index ca420d2..9d254b7 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pro
+++ b/Source/JavaScriptCore/JavaScriptCore.pro
@@ -205,6 +205,7 @@ SOURCES += \
runtime/StringConstructor.cpp \
runtime/StringObject.cpp \
runtime/StringPrototype.cpp \
+ runtime/StringRecursionChecker.cpp \
runtime/StructureChain.cpp \
runtime/Structure.cpp \
runtime/TimeoutChecker.cpp \
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 1ddc251..12310d8 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -1246,6 +1246,14 @@
>
</File>
<File
+ RelativePath="..\..\runtime\StringRecursionChecker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\StringRecursionChecker.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\Structure.cpp"
>
</File>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 0f9b4ab..358e38c 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -294,6 +294,7 @@
932F5BEA0822A1C700736975 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
933040040E6A749400786E6A /* SmallStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 93303FEA0E6A72C000786E6A /* SmallStrings.h */; settings = {ATTRIBUTES = (Private, ); }; };
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93303FE80E6A72B500786E6A /* SmallStrings.cpp */; };
+ 9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93345A8712D838C400302BE3 /* StringRecursionChecker.cpp */; };
933F5CDC1269229B0049191E /* NullPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 933F5CDB126922690049191E /* NullPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
937013480CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 937013470CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp */; settings = {COMPILER_FLAGS = "-Wno-sign-compare"; }; };
93854A9A12C93D3B00DAAF77 /* NullPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93854A9912C93D3B00DAAF77 /* NullPtr.cpp */; };
@@ -925,6 +926,8 @@
932F5BE10822A1C700736975 /* jsc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jsc; sourceTree = BUILT_PRODUCTS_DIR; };
93303FE80E6A72B500786E6A /* SmallStrings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmallStrings.cpp; sourceTree = "<group>"; };
93303FEA0E6A72C000786E6A /* SmallStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallStrings.h; sourceTree = "<group>"; };
+ 93345A8712D838C400302BE3 /* StringRecursionChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringRecursionChecker.cpp; sourceTree = "<group>"; };
+ 93345A8812D838C400302BE3 /* StringRecursionChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringRecursionChecker.h; sourceTree = "<group>"; };
933A349A038AE7C6008635CE /* Identifier.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Identifier.h; sourceTree = "<group>"; tabWidth = 8; };
933A349D038AE80F008635CE /* Identifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Identifier.cpp; sourceTree = "<group>"; tabWidth = 8; };
933F5CDB126922690049191E /* NullPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullPtr.h; sourceTree = "<group>"; };
@@ -1867,6 +1870,8 @@
BC18C3C40E16EE3300B34460 /* StringObjectThatMasqueradesAsUndefined.h */,
BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */,
BC18C3C60E16EE3300B34460 /* StringPrototype.h */,
+ 93345A8712D838C400302BE3 /* StringRecursionChecker.cpp */,
+ 93345A8812D838C400302BE3 /* StringRecursionChecker.h */,
BCDE3AB00E6C82CF001453A7 /* Structure.cpp */,
BCDE3AB10E6C82CF001453A7 /* Structure.h */,
7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */,
@@ -2873,6 +2878,7 @@
86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
+ 9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index ab0c3d4..7615ffc 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
- * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2003 Peter Kelly (pmk at post.com)
* Copyright (C) 2006 Alexey Proskuryakov (ap at nypop.com)
*
@@ -32,6 +32,7 @@
#include "Lookup.h"
#include "ObjectPrototype.h"
#include "Operations.h"
+#include "StringRecursionChecker.h"
#include <algorithm>
#include <wtf/Assertions.h>
#include <wtf/HashSet.h>
@@ -168,15 +169,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
return throwVMTypeError(exec);
JSArray* thisObj = asArray(thisValue);
- HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
- if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
- return throwVMError(exec, createStackOverflowError(exec));
- }
-
- bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
- if (alreadyVisited)
- return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoiding infinite recursion.
+ StringRecursionChecker checker(exec, thisObj);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned totalSize = length ? length - 1 : 0;
@@ -209,7 +204,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
if (exec->hadException())
break;
}
- arrayVisitedElements.remove(thisObj);
if (!totalSize)
return JSValue::encode(jsEmptyString(exec));
Vector<UChar> buffer;
@@ -234,15 +228,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
return throwVMTypeError(exec);
JSObject* thisObj = asArray(thisValue);
- HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
- if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
- return throwVMError(exec, createStackOverflowError(exec));
- }
-
- bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
- if (alreadyVisited)
- return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion.
+ StringRecursionChecker checker(exec, thisObj);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
JSStringBuilder strBuffer;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
@@ -264,7 +252,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
strBuffer.append(str);
}
}
- arrayVisitedElements.remove(thisObj);
+
return JSValue::encode(strBuffer.build(exec));
}
@@ -272,15 +260,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
- HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
- if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
- return throwVMError(exec, createStackOverflowError(exec));
- }
-
- bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
- if (alreadyVisited)
- return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion.
+ StringRecursionChecker checker(exec, thisObj);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
JSStringBuilder strBuffer;
@@ -335,7 +317,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
if (!element.isUndefinedOrNull())
strBuffer.append(element.toString(exec));
}
- arrayVisitedElements.remove(thisObj);
+
return JSValue::encode(strBuffer.build(exec));
}
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
index d18e7d8..d8fc829 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -26,6 +26,7 @@
#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
+#include "StringRecursionChecker.h"
#include "UString.h"
namespace JSC {
@@ -47,6 +48,11 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, No
EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+
+ StringRecursionChecker checker(exec, thisObj);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
+
JSValue name = thisObj->get(exec, exec->propertyNames().name);
JSValue message = thisObj->get(exec, exec->propertyNames().message);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index a24732a..1c3af2a 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -214,7 +214,7 @@ namespace JSC {
JSGlobalObject* head;
JSGlobalObject* dynamicGlobalObject;
- HashSet<JSObject*> arrayVisitedElements;
+ HashSet<JSObject*> stringRecursionCheckVisitedObjects;
Stringifier* firstStringifierToMark;
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 04bcc3b..a7c447d 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -34,6 +34,7 @@
#include "RegExpObject.h"
#include "RegExp.h"
#include "RegExpCache.h"
+#include "StringRecursionChecker.h"
#include "UStringConcatenate.h"
namespace JSC {
@@ -111,15 +112,21 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec)
return throwVMTypeError(exec);
}
+ RegExpObject* thisObject = asRegExpObject(thisValue);
+
+ StringRecursionChecker checker(exec, thisObject);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
+
char postfix[5] = { '/', 0, 0, 0, 0 };
int index = 1;
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
+ if (thisObject->get(exec, exec->propertyNames().global).toBoolean(exec))
postfix[index++] = 'g';
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
+ if (thisObject->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
postfix[index++] = 'i';
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
+ if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean(exec))
postfix[index] = 'm';
- UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
+ UString source = thisObject->get(exec, exec->propertyNames().source).toString(exec);
// If source is empty, use "/(?:)/" to avoid colliding with comment syntax
return JSValue::encode(jsMakeNontrivialString(exec, "/", source.length() ? source : UString("(?:)"), postfix));
}
diff --git a/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp b/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp
new file mode 100644
index 0000000..4e74735
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "StringRecursionChecker.h"
+
+#include "Error.h"
+#include "ExceptionHelpers.h"
+
+namespace JSC {
+
+EncodedJSValue StringRecursionChecker::throwStackOverflowError()
+{
+ return throwVMError(m_exec, createStackOverflowError(m_exec));
+}
+
+EncodedJSValue StringRecursionChecker::emptyString()
+{
+ return JSValue::encode(jsEmptyString(m_exec));
+}
+
+}
diff --git a/Source/JavaScriptCore/runtime/StringRecursionChecker.h b/Source/JavaScriptCore/runtime/StringRecursionChecker.h
new file mode 100644
index 0000000..314f14e
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/StringRecursionChecker.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef StringRecursionChecker_h
+#define StringRecursionChecker_h
+
+#include "Interpreter.h"
+
+namespace JSC {
+
+class StringRecursionChecker {
+ WTF_MAKE_NONCOPYABLE(StringRecursionChecker);
+
+public:
+ StringRecursionChecker(ExecState*, JSObject* thisObject);
+ ~StringRecursionChecker();
+
+ EncodedJSValue earlyReturnValue() const; // 0 if everything is OK, value to return for failure cases
+
+private:
+ EncodedJSValue throwStackOverflowError();
+ EncodedJSValue emptyString();
+ EncodedJSValue performCheck();
+
+ ExecState* m_exec;
+ JSObject* m_thisObject;
+ EncodedJSValue m_earlyReturnValue;
+};
+
+inline EncodedJSValue StringRecursionChecker::performCheck()
+{
+ int size = m_exec->globalData().stringRecursionCheckVisitedObjects.size();
+ if (size >= MaxSmallThreadReentryDepth && size >= m_exec->globalData().maxReentryDepth)
+ return throwStackOverflowError();
+ bool alreadyVisited = !m_exec->globalData().stringRecursionCheckVisitedObjects.add(m_thisObject).second;
+ if (alreadyVisited)
+ return emptyString(); // Return empty string to avoid infinite recursion.
+ return 0; // Indicate success.
+}
+
+inline StringRecursionChecker::StringRecursionChecker(ExecState* exec, JSObject* thisObject)
+ : m_exec(exec)
+ , m_thisObject(thisObject)
+ , m_earlyReturnValue(performCheck())
+{
+}
+
+inline EncodedJSValue StringRecursionChecker::earlyReturnValue() const
+{
+ return m_earlyReturnValue;
+}
+
+inline StringRecursionChecker::~StringRecursionChecker()
+{
+ if (m_earlyReturnValue)
+ return;
+ ASSERT(m_exec->globalData().stringRecursionCheckVisitedObjects.contains(m_thisObject));
+ m_exec->globalData().stringRecursionCheckVisitedObjects.remove(m_thisObject);
+}
+
+}
+
+#endif
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list