Title: [197457] trunk/Source/_javascript_Core
- Revision
- 197457
- Author
- [email protected]
- Date
- 2016-03-02 11:17:18 -0800 (Wed, 02 Mar 2016)
Log Message
SIGSEGV in Proxy [[Get]] and [[Set]] recursion
https://bugs.webkit.org/show_bug.cgi?id=154854
Reviewed by Yusuke Suzuki.
We need to be aware of the possibility that the VM
may recurse and that we can stack overflow.
* runtime/ProxyObject.cpp:
(JSC::performProxyGet):
(JSC::ProxyObject::performPut):
* tests/stress/proxy-get-and-set-recursion-stack-overflow.js: Added.
(assert):
(testStackOverflowGet):
(testStackOverflowIndexedGet):
(testStackOverflowSet):
(testStackOverflowIndexedSet):
Modified Paths
Added Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (197456 => 197457)
--- trunk/Source/_javascript_Core/ChangeLog 2016-03-02 18:54:03 UTC (rev 197456)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-03-02 19:17:18 UTC (rev 197457)
@@ -1,3 +1,23 @@
+2016-03-02 Saam barati <[email protected]>
+
+ SIGSEGV in Proxy [[Get]] and [[Set]] recursion
+ https://bugs.webkit.org/show_bug.cgi?id=154854
+
+ Reviewed by Yusuke Suzuki.
+
+ We need to be aware of the possibility that the VM
+ may recurse and that we can stack overflow.
+
+ * runtime/ProxyObject.cpp:
+ (JSC::performProxyGet):
+ (JSC::ProxyObject::performPut):
+ * tests/stress/proxy-get-and-set-recursion-stack-overflow.js: Added.
+ (assert):
+ (testStackOverflowGet):
+ (testStackOverflowIndexedGet):
+ (testStackOverflowSet):
+ (testStackOverflowIndexedSet):
+
2016-03-02 Benjamin Poulain <[email protected]>
[JSC] Use a Move without REX byte when possible
Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.cpp (197456 => 197457)
--- trunk/Source/_javascript_Core/runtime/ProxyObject.cpp 2016-03-02 18:54:03 UTC (rev 197456)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.cpp 2016-03-02 19:17:18 UTC (rev 197457)
@@ -80,6 +80,11 @@
static EncodedJSValue performProxyGet(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName)
{
VM& vm = exec->vm();
+ if (!vm.isSafeToRecurse()) {
+ throwStackOverflowError(exec);
+ return JSValue::encode(JSValue());
+ }
+
JSObject* thisObject = jsCast<JSObject*>(JSValue::decode(thisValue)); // This might be a value where somewhere in __proto__ chain lives a ProxyObject.
JSObject* proxyObjectAsObject = thisObject;
// FIXME: make it so that custom getters take both the |this| value and the slotBase (property holder).
@@ -345,6 +350,10 @@
void ProxyObject::performPut(ExecState* exec, JSValue putValue, JSValue thisValue, PropertyName propertyName, PerformDefaultPutFunction performDefaultPut)
{
VM& vm = exec->vm();
+ if (!vm.isSafeToRecurse()) {
+ throwStackOverflowError(exec);
+ return;
+ }
if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid())))
return performDefaultPut();
Added: trunk/Source/_javascript_Core/tests/stress/proxy-get-and-set-recursion-stack-overflow.js (0 => 197457)
--- trunk/Source/_javascript_Core/tests/stress/proxy-get-and-set-recursion-stack-overflow.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/proxy-get-and-set-recursion-stack-overflow.js 2016-03-02 19:17:18 UTC (rev 197457)
@@ -0,0 +1,67 @@
+function assert(b) {
+ if (!b)
+ throw new Error('bad assertion');
+}
+
+function testStackOverflowGet() {
+ let threw = false;
+ try {
+ let o = {};
+ let p = new Proxy(o, {});
+ Object.setPrototypeOf(o, p);
+ p.anyField;
+ } catch(e) {
+ threw = true;
+ assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+ }
+ assert(threw);
+}
+
+function testStackOverflowIndexedGet(i) {
+ let threw = false;
+ try {
+ let o = {};
+ let p = new Proxy(o, {});
+ Object.setPrototypeOf(o, p);
+ p[i];
+ } catch(e) {
+ threw = true;
+ assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+ }
+ assert(threw);
+}
+
+function testStackOverflowSet() {
+ let threw = false;
+ try {
+ let o = {};
+ let p = new Proxy(o, {});
+ Object.setPrototypeOf(o, p);
+ p.anyField = 50;
+ } catch(e) {
+ threw = true;
+ assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+ }
+ assert(threw);
+}
+
+function testStackOverflowIndexedSet(i) {
+ let threw = false;
+ try {
+ let o = {};
+ let p = new Proxy(o, {});
+ Object.setPrototypeOf(o, p);
+ p[i] = 50;
+ } catch(e) {
+ threw = true;
+ assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+ }
+ assert(threw);
+}
+
+for (let i = 0; i < 250; i++) {
+ testStackOverflowGet();
+ testStackOverflowIndexedGet(i);
+ testStackOverflowSet();
+ testStackOverflowIndexedSet(i);
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes