Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
No crash when property 'x' is assigned

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS successfullyParsed is true

TEST COMPLETE

94 changes: 94 additions & 0 deletions LayoutTests/fast/dom/non-reified-event-isTrusted-ic-crash.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html>
<body>
<script src="../../resources/js-test.js"></script>
<script>
description("No crash when property 'x' is assigned");

// This structure has a non-reified static property "isTrusted".
const EVENT = new Event('a');


function opt(use_event, proxy) {
let tmp = Object.create(null);
if (use_event)
tmp = Object.create(EVENT);

tmp.isTrusted = 1; // Here the compiler expects that it'll transition but at runtime it'll fail due to the setter from EVENT.

tmp.a0 = 0x1111;
tmp.a1 = 0x2222;
tmp.a2 = 0x3333;
tmp.a3 = 0x4444;
tmp.a4 = 0x5555;
tmp.a5 = 0x6666;

proxy.set_getter_on = tmp;

const value = tmp.a5;

return value;
}


function initialize() {
{
const object = Object.create(EVENT);
Object.defineProperty(object, 'isTrusted', {value: 1, writable: true, enumerable: true, configurable: true});

object.a0 = 1;
object.a1 = 1;
object.a2 = 1;
object.a3 = 1;
object.a4 = 1;
object.a5 = 1;
}

{
const object = Object.create(EVENT);

object.a0 = 1;
object.a1 = 1;
object.a2 = 1;
object.a3 = 1;
object.a4 = 1;
object.a5 = 1;
}
}


function main() {
const proxy = new Proxy({}, {
set: (object, property, value) => {
const tmp = {};
tmp[26] = 2.3023e-320;
value[26] = 1.1;

return true;
}
});

initialize();

for (let i = 0; i < 1000; i++) {
opt(/* use_event */ false, /* proxy */ 1.1);
opt(/* use_event */ true, /* proxy */ 1.1);
}

if (window.testRunner)
testRunner.waitUntilDone();

setTimeout(() => {
const value = opt(/* use_event */ true, proxy);

// Should crash here.
value.x = 1234;

if (window.testRunner)
testRunner.notifyDone();
}, 100);
}

main();

</script>
8 changes: 8 additions & 0 deletions Source/JavaScriptCore/bytecode/PropertyCondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ bool PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint(
if (PropertyConditionInternal::verbose)
dataLog("Invalid because its put() override may treat ", uid(), " property as read-only.\n");
return false;
} else if (structure->hasNonReifiedStaticProperties()) {
if (auto entry = structure->findPropertyHashEntry(uid())) {
if (entry->value->attributes() & (PropertyAttribute::ReadOnlyOrAccessorOrCustomAccessor | PropertyAttribute::CustomValue)) {
if (PropertyConditionInternal::verbose)
dataLog("Invalid because we expected not to have a setter, but we have one in non-reified static property table: ", uid(), ".\n");
return false;
}
}
}

if (structure->hasPolyProto()) {
Expand Down