RESOLVED FIXED Bug 154548
InternalFunction::createSubclassStructure doesn't take into account that get() might throw
https://bugs.webkit.org/show_bug.cgi?id=154548
Summary InternalFunction::createSubclassStructure doesn't take into account that get(...
Saam Barati
Reported 2016-02-22 12:13:06 PST
This leads to bad things. It does: ``` JSObject* prototype = jsDynamicCast<JSObject*>(get(blah)); if (prototype) { ... } ``` but, the return result from get() is always invalid when we throw an exception. We often have code that does this: ``` return throwVMTypeError(blah); ``` So, the above code snippet will successfully cast the result as an object, which leads to total failure because an exception was thrown.
Attachments
WIP (17.79 KB, patch)
2016-02-22 14:29 PST, Saam Barati
no flags
patch (21.20 KB, patch)
2016-02-22 15:11 PST, Saam Barati
mark.lam: review-
patch (22.04 KB, patch)
2016-02-22 15:54 PST, Saam Barati
no flags
patch (21.97 KB, patch)
2016-02-22 15:55 PST, Saam Barati
ggaren: review+
Saam Barati
Comment 1 2016-02-22 14:29:06 PST
Keith Miller
Comment 2 2016-02-22 14:35:40 PST
Comment on attachment 271956 [details] WIP View in context: https://bugs.webkit.org/attachment.cgi?id=271956&action=review Looks good overall, one minor nit though. > Source/JavaScriptCore/runtime/StringConstructor.cpp:137 > + return JSValue::encode(StringObject::create(vm, structure, exec->uncheckedArgument(0).toString(exec))); I think this would be cleaner as: Structure* structure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->stringObjectStructure()); if (exec->hadException()) return JSValue::encode(JSValue()); if (!exec->argumentCount()) return JSValue::encode(StringObject::create(vm, InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->stringObjectStructure()))); return JSValue::encode(StringObject::create(vm, InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->stringObjectStructure()), exec->uncheckedArgument(0).toString(exec)));
Keith Miller
Comment 3 2016-02-22 14:37:18 PST
(In reply to comment #2) > Comment on attachment 271956 [details] > WIP > > View in context: > https://bugs.webkit.org/attachment.cgi?id=271956&action=review > > Looks good overall, one minor nit though. > > > Source/JavaScriptCore/runtime/StringConstructor.cpp:137 > > + return JSValue::encode(StringObject::create(vm, structure, exec->uncheckedArgument(0).toString(exec))); > > I think this would be cleaner as: > > Structure* structure = InternalFunction::createSubclassStructure(exec, > exec->newTarget(), globalObject->stringObjectStructure()); > if (exec->hadException()) > return JSValue::encode(JSValue()); > > if (!exec->argumentCount()) > return JSValue::encode(StringObject::create(vm, > InternalFunction::createSubclassStructure(exec, exec->newTarget(), > globalObject->stringObjectStructure()))); > > return JSValue::encode(StringObject::create(vm, > InternalFunction::createSubclassStructure(exec, exec->newTarget(), > globalObject->stringObjectStructure()), > exec->uncheckedArgument(0).toString(exec))); Whoops, this should be: Structure* structure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->stringObjectStructure()); if (exec->hadException()) return JSValue::encode(JSValue()); if (!exec->argumentCount()) return JSValue::encode(StringObject::create(vm, structure)); return JSValue::encode(StringObject::create(vm, structure, exec->uncheckedArgument(0).toString(exec)));
Saam Barati
Comment 4 2016-02-22 15:11:08 PST
WebKit Commit Bot
Comment 5 2016-02-22 15:13:33 PST
Attachment 271959 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/runtime/RegExpConstructor.cpp:270: Multi line control clauses should use braces. [whitespace/braces] [4] ERROR: Source/JavaScriptCore/runtime/RegExpConstructor.cpp:272: Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3] Total errors found: 2 in 19 files If any of these errors are false positives, please file a bug against check-webkit-style.
Andreas Kling
Comment 6 2016-02-22 15:27:12 PST
Comment on attachment 271959 [details] patch r=me
Mark Lam
Comment 7 2016-02-22 15:27:49 PST
Comment on attachment 271959 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=271959&action=review > Source/JavaScriptCore/tests/stress/create-subclass-structure-might-throw.js:6 > +let targets = [Function, String, Array]; Why not also test WeakSet, WeakMap, and the other types that you fixed in this patch?
Mark Lam
Comment 8 2016-02-22 15:33:51 PST
Comment on attachment 271959 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=271959&action=review > Source/JavaScriptCore/runtime/JSGlobalObject.h:735 > + if (exec->hadException()) > + return nullptr; This exception check should be for both the if case as well because arrayStructureForProfileDuringAllocation() calls arrayStructureForIndexingTypeDuringAllocation().
Mark Lam
Comment 9 2016-02-22 15:37:05 PST
Comment on attachment 271959 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=271959&action=review > Source/JavaScriptCore/runtime/InternalFunction.cpp:105 > JSObject* prototype = jsDynamicCast<JSObject*>(newTarget.get(exec, exec->propertyNames().prototype)); > + if (exec->hadException()) > + return nullptr; In the if case above, we're also casting newTarget.get() to get a prototype. You can at least assert that it won't have an exception if it should not throw.
Saam Barati
Comment 10 2016-02-22 15:54:26 PST
Created attachment 271960 [details] patch fixed suggestions
Saam Barati
Comment 11 2016-02-22 15:55:33 PST
Geoffrey Garen
Comment 12 2016-02-22 15:59:10 PST
Comment on attachment 271962 [details] patch r=me
Mark Lam
Comment 13 2016-02-22 16:00:54 PST
Comment on attachment 271962 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=271962&action=review r=me too > Source/JavaScriptCore/tests/stress/create-subclass-structure-might-throw.js:6 > +let targets = [Function, String, Array, Set, Map, WeakSet, WeakMap, RegExp, Number, Promise, Date, Boolean, Error, TypeError, SyntaxError, ArrayBuffer, Int32Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Uint32Array, Float32Array, Float64Array]; I think DataView is made the same way as the TypeArrays. Maybe you should add that.
Saam Barati
Comment 14 2016-02-22 16:51:41 PST
Note You need to log in before you can comment on or make changes to this bug.