Title: [202415] trunk
Revision
202415
Author
[email protected]
Date
2016-06-23 21:39:35 -0700 (Thu, 23 Jun 2016)

Log Message

OOM Assertion failure in Array.prototype.toString
https://bugs.webkit.org/show_bug.cgi?id=158793

Patch by Benjamin Poulain <[email protected]> on 2016-06-23
Reviewed by Saam Barati.

Source/_javascript_Core:

JSString::create() taking a StringImpl was using a signed integer
for the length of the string.
The problem is StringImpl uses an unsigned integer. When a large string
was passed to JSString, the signed integer would be negative and crash
JSString.

* runtime/JSString.h:
(JSC::JSString::create):

LayoutTests:

* js/script-tests/stringimpl-to-jsstring-on-large-strings-1.js: Added.
(string_appeared_here.createStrings):
* js/script-tests/stringimpl-to-jsstring-on-large-strings-2.js: Added.
(string_appeared_here.createRegexp):
(catch):
* js/script-tests/stringimpl-to-jsstring-on-large-strings-3.js: Added.
(string_appeared_here.createStrings):
(catch):
* js/stringimpl-to-jsstring-on-large-strings-1-expected.txt: Added.
* js/stringimpl-to-jsstring-on-large-strings-1.html: Added.
* js/stringimpl-to-jsstring-on-large-strings-2-expected.txt: Added.
* js/stringimpl-to-jsstring-on-large-strings-2.html: Added.
* js/stringimpl-to-jsstring-on-large-strings-3-expected.txt: Added.
* js/stringimpl-to-jsstring-on-large-strings-3.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (202414 => 202415)


--- trunk/LayoutTests/ChangeLog	2016-06-24 04:08:48 UTC (rev 202414)
+++ trunk/LayoutTests/ChangeLog	2016-06-24 04:39:35 UTC (rev 202415)
@@ -1,3 +1,25 @@
+2016-06-23  Benjamin Poulain  <[email protected]>
+
+        OOM Assertion failure in Array.prototype.toString
+        https://bugs.webkit.org/show_bug.cgi?id=158793
+
+        Reviewed by Saam Barati.
+
+        * js/script-tests/stringimpl-to-jsstring-on-large-strings-1.js: Added.
+        (string_appeared_here.createStrings):
+        * js/script-tests/stringimpl-to-jsstring-on-large-strings-2.js: Added.
+        (string_appeared_here.createRegexp):
+        (catch):
+        * js/script-tests/stringimpl-to-jsstring-on-large-strings-3.js: Added.
+        (string_appeared_here.createStrings):
+        (catch):
+        * js/stringimpl-to-jsstring-on-large-strings-1-expected.txt: Added.
+        * js/stringimpl-to-jsstring-on-large-strings-1.html: Added.
+        * js/stringimpl-to-jsstring-on-large-strings-2-expected.txt: Added.
+        * js/stringimpl-to-jsstring-on-large-strings-2.html: Added.
+        * js/stringimpl-to-jsstring-on-large-strings-3-expected.txt: Added.
+        * js/stringimpl-to-jsstring-on-large-strings-3.html: Added.
+
 2016-06-23  Brady Eidson  <[email protected]>
 
         Retrieving Blobs from IndexedDB using cursors fails in WK2 (Sandboxing)

Added: trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-1.js (0 => 202415)


--- trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-1.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-1.js	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,34 @@
+"use strict"
+
+// Based on André Bargull's test case.
+// The test pass if it does not crash.
+// see https://bugs.webkit.org/show_bug.cgi?id=158793.
+
+function createStrings() {
+    let p = "a".repeat(0x7ffffff);
+    if (p.length != 0x7ffffff)
+        debug("Failed \"a\".repeat(0x7ffffff)");
+
+    let r = [
+      p, p, p, p, p,
+      p, p, p, p, p,
+      p, p, p, p, p,
+      p, p, p, p, p,
+      p, p, p, p, p
+    ].toString();
+    if (r.length !== 0x7ffffff * 25 + 24)
+        debug("Failed to generate r");
+
+    // This should always overflow with 32bits length.
+    let s = [
+      p, p, p, p, p, p, p, p,
+      p, p, p, p, p, p, p, p,
+      p, p, p, p, p, p, p, p,
+      p, p, p, p, p, p, p, p,
+    ].toString();
+    if (s.length !== 0x7ffffff * 32 + 31)
+        debug("Failed to generate s");
+
+    return [p, r, s];
+}
+shouldThrow("createStrings()", '"Error: Out of memory"');

Added: trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-2.js (0 => 202415)


--- trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-2.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-2.js	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,18 @@
+"use strict"
+
+// Based on André Bargull's test case.
+// The test pass if it does not crash.
+// see https://bugs.webkit.org/show_bug.cgi?id=158793.
+
+function createRegexp() {
+    var s = "a".repeat(0x3fffffff);
+    var r = RegExp.prototype.toString.call({
+        source: s,
+        flags: s,
+    });
+    return [s, r];
+}
+try {
+    createRegexp();
+} catch (e) { }
+debug("PASS: no crash");

Added: trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-3.js (0 => 202415)


--- trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-3.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/stringimpl-to-jsstring-on-large-strings-3.js	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,37 @@
+"use strict"
+
+// This test passes if it does not crash.
+function createStrings() {
+    let a = "a".repeat(0x7fffffff);
+    if (a.length !== 0x7fffffff)
+        debug("Failed to create a string of length 0x7ffffffff");
+
+    a = "a".repeat(0x80000000);
+    if (a.length !== 0x80000000)
+        debug("Failed to create a string of length 0x80000000");
+
+    a = "a".repeat(0x7fffffff - 2);
+    if (a.length != 0x7fffffff - 2)
+        debug("Failed to create a string of length 0x7fffffff - 2");
+
+    let b = [a, 'b'];
+    let c = b.toString();
+    if (b.length !== 0x7ffffffff)
+        debug("Failed to join a string of length 0x7ffffffff");
+
+    a = "a".repeat(0x7fffffff - 1);
+    if (a.length != 0x7fffffff - 1)
+        debug("Failed to create a string of length 0x7fffffff - 1");
+
+    b = [a, 'b'];
+    c = b.toString();
+    if (b.length !== 0x80000000)
+        debug("Failed to join a string of length 0x80000000");
+    return [a, b, c];
+}
+try {
+    createStrings();
+} catch (e) { }
+
+debug("PASS: the test did not crash")
+

Added: trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-1-expected.txt (0 => 202415)


--- trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-1-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-1-expected.txt	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,5 @@
+PASS createStrings() threw exception Error: Out of memory.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-1.html (0 => 202415)


--- trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-1.html	                        (rev 0)
+++ trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-1.html	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,10 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-2-expected.txt (0 => 202415)


--- trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-2-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-2-expected.txt	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,5 @@
+PASS: no crash
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-2.html (0 => 202415)


--- trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-2.html	                        (rev 0)
+++ trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-2.html	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,10 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-3-expected.txt (0 => 202415)


--- trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-3-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-3-expected.txt	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,5 @@
+PASS: the test did not crash
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-3.html (0 => 202415)


--- trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-3.html	                        (rev 0)
+++ trunk/LayoutTests/js/stringimpl-to-jsstring-on-large-strings-3.html	2016-06-24 04:39:35 UTC (rev 202415)
@@ -0,0 +1,10 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (202414 => 202415)


--- trunk/Source/_javascript_Core/ChangeLog	2016-06-24 04:08:48 UTC (rev 202414)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-06-24 04:39:35 UTC (rev 202415)
@@ -1,3 +1,19 @@
+2016-06-23  Benjamin Poulain  <[email protected]>
+
+        OOM Assertion failure in Array.prototype.toString
+        https://bugs.webkit.org/show_bug.cgi?id=158793
+
+        Reviewed by Saam Barati.
+
+        JSString::create() taking a StringImpl was using a signed integer
+        for the length of the string.
+        The problem is StringImpl uses an unsigned integer. When a large string
+        was passed to JSString, the signed integer would be negative and crash
+        JSString.
+
+        * runtime/JSString.h:
+        (JSC::JSString::create):
+
 2016-06-23  Joseph Pecoraro  <[email protected]> and Yusuke Suzuki  <[email protected]>
 
         [JSC] Implement isFinite / isNaN in JS and make DFG ToNumber accept non number values

Modified: trunk/Source/_javascript_Core/runtime/JSString.h (202414 => 202415)


--- trunk/Source/_javascript_Core/runtime/JSString.h	2016-06-24 04:08:48 UTC (rev 202414)
+++ trunk/Source/_javascript_Core/runtime/JSString.h	2016-06-24 04:39:35 UTC (rev 202415)
@@ -132,8 +132,7 @@
     static JSString* create(VM& vm, PassRefPtr<StringImpl> value)
     {
         ASSERT(value);
-        int32_t length = value->length();
-        RELEASE_ASSERT(length >= 0);
+        unsigned length = value->length();
         size_t cost = value->cost();
         JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
         newString->finishCreation(vm, length, cost);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to