REGRESSION(r200383): Setting lazily initialized properties across frame boundaries crashes
https://bugs.webkit.org/show_bug.cgi?id=157333

Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

I forgot to add logic for lazy properties in putEntry(). It turns out that it's easy to
add.

* runtime/Lookup.h:
(JSC::putEntry):
* runtime/PropertySlot.h:

LayoutTests:

This is JoePeck's original test case. It used to crash and now it doesn't crash anymore.

* js/dom/cross-window-put-math-expected.txt: Added.
* js/dom/cross-window-put-math.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@200406 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index f3cf28a..741e8ee 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2016-05-03  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r200383): Setting lazily initialized properties across frame boundaries crashes
+        https://bugs.webkit.org/show_bug.cgi?id=157333
+
+        Reviewed by Benjamin Poulain.
+        
+        This is JoePeck's original test case. It used to crash and now it doesn't crash anymore.
+
+        * js/dom/cross-window-put-math-expected.txt: Added.
+        * js/dom/cross-window-put-math.html: Added.
+
 2016-05-03  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Improve Symbol() to string coercion error message
diff --git a/LayoutTests/js/dom/cross-window-put-math-expected.txt b/LayoutTests/js/dom/cross-window-put-math-expected.txt
new file mode 100644
index 0000000..b0b92d8
--- /dev/null
+++ b/LayoutTests/js/dom/cross-window-put-math-expected.txt
@@ -0,0 +1,9 @@
+
+Test storing to a lazy global property.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/dom/cross-window-put-math.html b/LayoutTests/js/dom/cross-window-put-math.html
new file mode 100644
index 0000000..a35a6b73
--- /dev/null
+++ b/LayoutTests/js/dom/cross-window-put-math.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<iframe id="x" src="data:text/html,<p>Hello</p>"></iframe>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description('Test storing to a lazy global property.');
+window.frames[0].Math = window.Math;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index e9c4591..d3121a3 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,5 +1,19 @@
 2016-05-03  Filip Pizlo  <fpizlo@apple.com>
 
+        REGRESSION(r200383): Setting lazily initialized properties across frame boundaries crashes
+        https://bugs.webkit.org/show_bug.cgi?id=157333
+
+        Reviewed by Benjamin Poulain.
+        
+        I forgot to add logic for lazy properties in putEntry(). It turns out that it's easy to
+        add.
+
+        * runtime/Lookup.h:
+        (JSC::putEntry):
+        * runtime/PropertySlot.h:
+
+2016-05-03  Filip Pizlo  <fpizlo@apple.com>
+
         References from code to Structures should be stronger than weak
         https://bugs.webkit.org/show_bug.cgi?id=157324
 
diff --git a/Source/JavaScriptCore/runtime/Lookup.h b/Source/JavaScriptCore/runtime/Lookup.h
index c7d4ced..af78abe 100644
--- a/Source/JavaScriptCore/runtime/Lookup.h
+++ b/Source/JavaScriptCore/runtime/Lookup.h
@@ -293,9 +293,10 @@
 // 'slot.thisValue()' is the object the put was originally performed on (in the case of a proxy, the proxy itself).
 inline bool putEntry(ExecState* exec, const HashTableValue* entry, JSObject* base, JSObject* thisValue, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
 {
-    if (entry->attributes() & BuiltinOrFunction) {
+    if (entry->attributes() & BuiltinOrFunctionOrLazyProperty) {
         if (!(entry->attributes() & ReadOnly)) {
-            // If this is a function put it as an override property.
+            // If this is a function or lazy property put then we just do the put because
+            // logically the object already had the property, so this is just a replace.
             if (JSObject* thisObject = jsDynamicCast<JSObject*>(thisValue))
                 thisObject->putDirect(exec->vm(), propertyName, value);
             return true;
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.h b/Source/JavaScriptCore/runtime/PropertySlot.h
index 74e7d8c..15403cd 100644
--- a/Source/JavaScriptCore/runtime/PropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PropertySlot.h
@@ -50,6 +50,7 @@
     ClassStructure    = 1 << 12, // property is a lazy class structure - only used by static hashtables
     PropertyCallback  = 1 << 13, // property that is a lazy property callback - only used by static hashtables
     BuiltinOrFunction = Builtin | Function, // helper only used by static hashtables
+    BuiltinOrFunctionOrLazyProperty = Builtin | Function | CellProperty | ClassStructure | PropertyCallback, // helper only used by static hashtables
     BuiltinOrFunctionOrAccessorOrLazyProperty = Builtin | Function | Accessor | CellProperty | ClassStructure | PropertyCallback, // helper only used by static hashtables
     BuiltinOrFunctionOrAccessorOrLazyPropertyOrConstant = Builtin | Function | Accessor | CellProperty | ClassStructure | PropertyCallback | ConstantInteger // helper only used by static hashtables
 };