WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
137814
crash when attempting to perform array iteration on a non-array with numeric keys not initialized
https://bugs.webkit.org/show_bug.cgi?id=137814
Summary
crash when attempting to perform array iteration on a non-array with numeric ...
Claude Pache
Reported
2014-10-17 02:16:25 PDT
The following JS code will crash WebKit. var b = Object.create(Array.iterator) for (var x of b) { console.log(x) } // boom The crash does not occur (and standard Array iteration is triggered) when some numeric key of the iterated object was initialized. var b = Object.create(Array.iterator) b[3] = 42 for (var x of b) { console.log(x) } // no crash
Attachments
test case (will crash on load)
(110 bytes, text/html)
2014-10-18 23:18 PDT
,
Alexey Proskuryakov
no flags
Details
the patch.
(12.61 KB, patch)
2014-10-27 17:24 PDT
,
Mark Lam
ggaren
: review+
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Claude Pache
Comment 1
2014-10-17 02:18:17 PDT
(In reply to
comment #0
)
> var b = Object.create(Array.iterator)
Replace with: var b = Object.create(Array.prototype)
Alexey Proskuryakov
Comment 2
2014-10-18 23:18:19 PDT
rdar://problem/17538114
Alexey Proskuryakov
Comment 3
2014-10-18 23:18:57 PDT
Created
attachment 240083
[details]
test case (will crash on load) Same test as attachment, ready to run.
Mark Lam
Comment 4
2014-10-20 17:16:32 PDT
Here's what I know so far: 1. The crash occurs in Specialized thunk code for array-iterator-next-value generated by arrayIteratorNextThunkGenerator(). 2. No DFG JIT is needed. But JIT'ting in general do need to be enabled because we need to generate the thunks. 3. It crashed because it's an expecting a non-zero butterfly pointer in the array object, but this is not true i.e. we've got NULL. 4. The classInfo of object being operated on (whose butterfly pointer is NULL) says that it is an ArrayIterator: (lldb) p *((JSObject*)$rdi)->structure()->classInfo() (const JSC::ClassInfo) $12 = { className = 0x0000000100a5ed86 "ArrayIterator" ... 5. The crashed code is executed because the object's iterationKind() is ArrayIterateValue. (lldb) p ((JSArrayIterator*)$rdi)->iterationKind() (JSC::ArrayIterationKind) $15 = ArrayIterateValue 6. The iterationKind we are generating the thunk of is ArrayIterateValue.
Geoffrey Garen
Comment 5
2014-10-21 14:51:24 PDT
I suspect the problem here is that we just neglected to consider the case where an ArrayIterator is used to iterate a non-Array. One thing that can happen in that case is that the butterfly pointer can be NULL.
Mark Lam
Comment 6
2014-10-21 16:53:09 PDT
More details: 7. If JSC_useJIT=false, we'll create an iterator JSFunction that points to JSArrayIterator's arrayIteratorNextValue() C++ function. If JSC_useJIT=true, we'll create an iterator JSFunction that uses the ArrayIteratorNextValueIntrinsic intrinsic thunk. The arrayIteratorNextValue() C++ function will first check to ensure the this object is a JSArrayIterator. The next step is to get the length property of the object. This ultimately results in a call to JSArray::getOwnPropertySlot() which special cases property "length" and sets the property to the return value of JSArray::length(). JSArray::length() calls JSObject::getArrayLength(). JSObject::getArrayLength() discovers that the object does not have any indexed properties yet, and returns a value of 0. In contrast, the ArrayIteratorNextValueIntrinsic thunk also checks if the object is a JSArrayIterator. Thereafter, it assumes that the iterated object has indexed properties and proceeds to grab the length from its butterfly. Since, the butterfly for an Object with no properties is 0, we crash. After I added a NULL check on the butterfly (and have the thunk take the slow path if the butterfly is NULL), the test case no longer crash. However, I need to parse the butterfly code some more to get a more comprehensive understanding of how the butterfly is shaped for JSObjects, JSArrays, and typed JSArrays. The NULL check I added averted the immediate crash, but the thunk is also making assumptions about the shape of the butterfly. I'll need to verify that those assumptions hold before I can conclude that this fix is appropriate.
Mark Lam
Comment 7
2014-10-22 13:12:13 PDT
(In reply to
comment #6
)
> 7. If JSC_useJIT=false, we'll create an iterator JSFunction that points to > JSArrayIterator's arrayIteratorNextValue() C++ function. > ... > The arrayIteratorNextValue() C++ function will first check to ensure the > this object is a JSArrayIterator. > The next step is to get the length property of the object. > ... > JSObject::getArrayLength() discovers that the object does not have any > indexed properties yet, and returns a value of 0.
Correction: JSObject::getPropertySlot() fails to find the “length” property in the Object, and looks up the prototype chain. The next object in the chain is the ArrayPrototype. JSArray::length() is run on the ArrayPrototype, and returns 0. JSArray::getOwnPropertySlot() also ends up setting the 0 “length” property on the ArrayPrototype, not the Object we’re testing.
Mark Lam
Comment 8
2014-10-27 17:24:24 PDT
Created
attachment 240513
[details]
the patch.
Geoffrey Garen
Comment 9
2014-10-27 22:25:35 PDT
Comment on
attachment 240513
[details]
the patch. View in context:
https://bugs.webkit.org/attachment.cgi?id=240513&action=review
r=me
> Source/JavaScriptCore/ChangeLog:12 > + may have been set on the iterated object. The thunk only check's the butterfly's
check's => checks
> Source/JavaScriptCore/jit/ThunkGenerators.cpp:1103 > + Jump nullButterfly = jit.branchPtr(SpecializedThunkJIT::Equal, SpecializedThunkJIT::regT2, TrustedImmPtr(0));
It's better to use branchTestPtr. Some of our assemblers will automatically optimize this to a test, and some won't.
Mark Lam
Comment 10
2014-10-27 22:27:18 PDT
Comment on
attachment 240513
[details]
the patch. Cancelling commit. Will apply feedback and commit manually.
Mark Lam
Comment 11
2014-10-27 22:48:24 PDT
Thanks for the review. Feedback has been applied, and the fix has ben landed in
r175243
: <
http://trac.webkit.org/r175243
>.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug