Title: [202966] trunk
Revision
202966
Author
[email protected]
Date
2016-07-07 23:25:34 -0700 (Thu, 07 Jul 2016)

Log Message

padStart/padEnd with Infinity produces unexpected result
https://bugs.webkit.org/show_bug.cgi?id=159543

Patch by Joseph Pecoraro <[email protected]> on 2016-07-07
Reviewed by Benjamin Poulain.

Source/_javascript_Core:

* builtins/GlobalOperations.js:
(globalPrivate.toLength):
Fix style.

* builtins/StringPrototype.js:
(padStart):
(padEnd):
After all observable operations, and after empty string has been handled,
throw an out of memory error if the resulting string would be greater
than the maximum string size.

* tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js:
(shouldThrow): Deleted.
* tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js:
(shouldThrow):
(testMeta):
* tests/es6/String.prototype_methods_String.prototype.padEnd.js:
(shouldThrow):
(TestToLength):
(TestMemoryLimits):
(TestMeta): Deleted.
* tests/es6/String.prototype_methods_String.prototype.padStart.js:
(shouldThrow):
(TestToLength):
(TestMemoryLimits):
Replace incorrect shouldThrow(..., errorType) with explicit shouldThrow(..., errorMessage).
The old shouldThrow would incorrectly succeed if the expected error type was just "Error".
Now we explicitly check the error message.

LayoutTests:

* js/script-tests/string-padend.js: Added.
(thisObject.toString):
(lengthObject.valueOf):
(fillObject.toString):
* js/script-tests/string-padstart.js: Added.
(thisObject.toString):
(lengthObject.valueOf):
(fillObject.toString):
* js/string-padend-expected.txt: Added.
* js/string-padend.html: Added.
* js/string-padstart-expected.txt: Added.
* js/string-padstart.html: Added.
Add some basic String.prototype.padStart/padEnd test coverage
that is not just in the _javascript_Core/tests/es6 directory.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (202965 => 202966)


--- trunk/LayoutTests/ChangeLog	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/LayoutTests/ChangeLog	2016-07-08 06:25:34 UTC (rev 202966)
@@ -1,3 +1,25 @@
+2016-07-07  Joseph Pecoraro  <[email protected]>
+
+        padStart/padEnd with Infinity produces unexpected result
+        https://bugs.webkit.org/show_bug.cgi?id=159543
+
+        Reviewed by Benjamin Poulain.
+
+        * js/script-tests/string-padend.js: Added.
+        (thisObject.toString):
+        (lengthObject.valueOf):
+        (fillObject.toString):
+        * js/script-tests/string-padstart.js: Added.
+        (thisObject.toString):
+        (lengthObject.valueOf):
+        (fillObject.toString):
+        * js/string-padend-expected.txt: Added.
+        * js/string-padend.html: Added.
+        * js/string-padstart-expected.txt: Added.
+        * js/string-padstart.html: Added.
+        Add some basic String.prototype.padStart/padEnd test coverage
+        that is not just in the _javascript_Core/tests/es6 directory.
+
 2016-07-07  Frederic Wang  <[email protected]>
 
         Bug 155792 - Basic implementation of mpadded

Added: trunk/LayoutTests/js/script-tests/string-padend.js (0 => 202966)


--- trunk/LayoutTests/js/script-tests/string-padend.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/string-padend.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -0,0 +1,83 @@
+description("This test checks the String.prototype.padEnd.");
+
+shouldBe('String.prototype.padEnd.length', '1');
+shouldBeEqualToString('String.prototype.padEnd.name', 'padEnd');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padEnd").configurable', 'true');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padEnd").enumerable', 'false');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padEnd").writable', 'true');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padEnd").get', 'undefined');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padEnd").set', 'undefined');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padEnd").value', 'String.prototype.padEnd');
+
+shouldBe("'foo'.padEnd()", "'foo'");
+shouldBe("'foo'.padEnd(+0)", "'foo'");
+shouldBe("'foo'.padEnd(-0)", "'foo'");
+shouldBe("'foo'.padEnd(1)", "'foo'");
+shouldBe("'foo'.padEnd(2)", "'foo'");
+shouldBe("'foo'.padEnd(-2)", "'foo'");
+shouldBe("'foo'.padEnd(10)",              "'foo       '");
+shouldBe("'foo'.padEnd(10, undefined)",   "'foo       '");
+shouldBe("'foo'.padEnd(10, 'x')",         "'fooxxxxxxx'");
+shouldBe("'foo'.padEnd(10.5, 'z')",       "'foozzzzzzz'");
+shouldBe("'foo'.padEnd(10, 'bar')",       "'foobarbarb'");
+shouldBe("'foo'.padEnd(10, '123456789')", "'foo1234567'");
+shouldBe("'foo'.padEnd(999, '')", "'foo'");
+shouldBe("''.padEnd(1, '')", "''");
+shouldBe("''.padEnd(2, 'bar')", "'ba'");
+shouldBe("'x'.padEnd(2, 'bar')", "'xb'");
+shouldBe("'xx'.padEnd(2, 'bar')", "'xx'");
+shouldBe("'xx'.padEnd(Math.PI, 'bar')", "'xxb'");
+
+// Coerce length (ToLength).
+shouldBe("''.padEnd(true, 'ABC')", "'A'");
+shouldBe("''.padEnd(false, 'ABC')", "''");
+shouldBe("''.padEnd(null, 'ABC')", "''");
+shouldBe("''.padEnd({}, 'ABC')", "''");
+shouldBe("''.padEnd(NaN, 'ABC')", "''");
+
+// Coerce fillString (ToString).
+shouldBe("'ABC'.padEnd(10, true)",  "'ABCtruetru'");
+shouldBe("'ABC'.padEnd(10, false)", "'ABCfalsefa'");
+shouldBe("'ABC'.padEnd(10, null)",  "'ABCnullnul'");
+shouldBe("'ABC'.padEnd(10, {})",    "'ABC[object'");
+shouldBe("'ABC'.padEnd(10, NaN)",   "'ABCNaNNaNN'");
+
+// Check out of memory errors.
+shouldNotThrow('"x".padEnd(Infinity, "")'); // Empty string filler is fine.
+shouldThrow('"x".padEnd(Infinity, "x")', "'Error: Out of memory'");
+shouldThrow('"x".padEnd(0x80000000, "x")', "'Error: Out of memory'");
+shouldThrow('"x".padEnd(0xFFFFFFFF, "x")', "'Error: Out of memory'");
+
+// Check side-effects.
+let sideEffects = "";
+let thisObject = new String("foo bar");
+let lengthObject = new Number(10);
+let fillObject = new String("X");
+
+sideEffects = "";
+thisObject.toString = function() { sideEffects += "A"; return this; };
+lengthObject.valueOf = function() { sideEffects += "B"; return this; };
+fillObject.toString = function() { sideEffects += "C"; return this; };
+shouldBeEqualToString("String.prototype.padEnd.call(thisObject, lengthObject, fillObject)", "foo barXXX");
+shouldBeEqualToString("sideEffects", "ABC");
+
+sideEffects = "";
+thisObject.toString = function() { throw "ERROR"; };
+lengthObject.valueOf = function() { sideEffects += "B"; return this; };
+fillObject.toString = function() { sideEffects += "C"; return this; };
+shouldThrow("String.prototype.padEnd.call(thisObject, lengthObject, fillObject)", "'ERROR'");
+shouldBeEqualToString("sideEffects", "");
+
+sideEffects = "";
+thisObject.toString = function() { sideEffects += "A"; return this; };
+lengthObject.valueOf = function() { throw "ERROR"; };
+fillObject.toString = function() { sideEffects += "C"; return this; };
+shouldThrow("String.prototype.padEnd.call(thisObject, lengthObject, fillObject)", "'ERROR'");
+shouldBeEqualToString("sideEffects", "A");
+
+sideEffects = "";
+thisObject.toString = function() { sideEffects += "A"; return this; };
+lengthObject.valueOf = function() { sideEffects += "B"; return this; };
+fillObject.toString = function() { throw "ERROR"; return this; };
+shouldThrow("String.prototype.padEnd.call(thisObject, lengthObject, fillObject)", "'ERROR'");
+shouldBeEqualToString("sideEffects", "AB");

Added: trunk/LayoutTests/js/script-tests/string-padstart.js (0 => 202966)


--- trunk/LayoutTests/js/script-tests/string-padstart.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/string-padstart.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -0,0 +1,83 @@
+description("This test checks the String.prototype.padStart.");
+
+shouldBe('String.prototype.padStart.length', '1');
+shouldBeEqualToString('String.prototype.padStart.name', 'padStart');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padStart").configurable', 'true');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padStart").enumerable', 'false');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padStart").writable', 'true');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padStart").get', 'undefined');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padStart").set', 'undefined');
+shouldBe('Object.getOwnPropertyDescriptor(String.prototype, "padStart").value', 'String.prototype.padStart');
+
+shouldBe("'foo'.padStart()", "'foo'");
+shouldBe("'foo'.padStart(+0)", "'foo'");
+shouldBe("'foo'.padStart(-0)", "'foo'");
+shouldBe("'foo'.padStart(1)", "'foo'");
+shouldBe("'foo'.padStart(2)", "'foo'");
+shouldBe("'foo'.padStart(-2)", "'foo'");
+shouldBe("'foo'.padStart(10)",              "'       foo'");
+shouldBe("'foo'.padStart(10, undefined)",   "'       foo'");
+shouldBe("'foo'.padStart(10, 'x')",         "'xxxxxxxfoo'");
+shouldBe("'foo'.padStart(10.5, 'z')",       "'zzzzzzzfoo'");
+shouldBe("'foo'.padStart(10, 'bar')",       "'barbarbfoo'");
+shouldBe("'foo'.padStart(10, '123456789')", "'1234567foo'");
+shouldBe("'foo'.padStart(999, '')", "'foo'");
+shouldBe("''.padStart(1, '')", "''");
+shouldBe("''.padStart(2, 'bar')", "'ba'");
+shouldBe("'x'.padStart(2, 'bar')", "'bx'");
+shouldBe("'xx'.padStart(2, 'bar')", "'xx'");
+shouldBe("'xx'.padStart(Math.PI, 'bar')", "'bxx'");
+
+// Coerce length (ToLength).
+shouldBe("''.padStart(true, 'ABC')", "'A'");
+shouldBe("''.padStart(false, 'ABC')", "''");
+shouldBe("''.padStart(null, 'ABC')", "''");
+shouldBe("''.padStart({}, 'ABC')", "''");
+shouldBe("''.padStart(NaN, 'ABC')", "''");
+
+// Coerce fillString (ToString).
+shouldBe("'ABC'.padStart(10, true)",  "'truetruABC'");
+shouldBe("'ABC'.padStart(10, false)", "'falsefaABC'");
+shouldBe("'ABC'.padStart(10, null)",  "'nullnulABC'");
+shouldBe("'ABC'.padStart(10, {})",    "'[objectABC'");
+shouldBe("'ABC'.padStart(10, NaN)",   "'NaNNaNNABC'");
+
+// Check out of memory errors.
+shouldNotThrow('"x".padStart(Infinity, "")'); // Empty string filler is fine.
+shouldThrow('"x".padStart(Infinity, "x")', "'Error: Out of memory'");
+shouldThrow('"x".padStart(0x80000000, "x")', "'Error: Out of memory'");
+shouldThrow('"x".padStart(0xFFFFFFFF, "x")', "'Error: Out of memory'");
+
+// Check side-effects.
+let sideEffects = "";
+let thisObject = new String("foo bar");
+let lengthObject = new Number(10);
+let fillObject = new String("X");
+
+sideEffects = "";
+thisObject.toString = function() { sideEffects += "A"; return this; };
+lengthObject.valueOf = function() { sideEffects += "B"; return this; };
+fillObject.toString = function() { sideEffects += "C"; return this; };
+shouldBeEqualToString("String.prototype.padStart.call(thisObject, lengthObject, fillObject)", "XXXfoo bar");
+shouldBeEqualToString("sideEffects", "ABC");
+
+sideEffects = "";
+thisObject.toString = function() { throw "ERROR"; };
+lengthObject.valueOf = function() { sideEffects += "B"; return this; };
+fillObject.toString = function() { sideEffects += "C"; return this; };
+shouldThrow("String.prototype.padStart.call(thisObject, lengthObject, fillObject)", "'ERROR'");
+shouldBeEqualToString("sideEffects", "");
+
+sideEffects = "";
+thisObject.toString = function() { sideEffects += "A"; return this; };
+lengthObject.valueOf = function() { throw "ERROR"; };
+fillObject.toString = function() { sideEffects += "C"; return this; };
+shouldThrow("String.prototype.padStart.call(thisObject, lengthObject, fillObject)", "'ERROR'");
+shouldBeEqualToString("sideEffects", "A");
+
+sideEffects = "";
+thisObject.toString = function() { sideEffects += "A"; return this; };
+lengthObject.valueOf = function() { sideEffects += "B"; return this; };
+fillObject.toString = function() { throw "ERROR"; return this; };
+shouldThrow("String.prototype.padStart.call(thisObject, lengthObject, fillObject)", "'ERROR'");
+shouldBeEqualToString("sideEffects", "AB");

Added: trunk/LayoutTests/js/string-padend-expected.txt (0 => 202966)


--- trunk/LayoutTests/js/string-padend-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/string-padend-expected.txt	2016-07-08 06:25:34 UTC (rev 202966)
@@ -0,0 +1,57 @@
+This test checks the String.prototype.padEnd.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS String.prototype.padEnd.length is 1
+PASS String.prototype.padEnd.name is "padEnd"
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padEnd").configurable is true
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padEnd").enumerable is false
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padEnd").writable is true
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padEnd").get is undefined
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padEnd").set is undefined
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padEnd").value is String.prototype.padEnd
+PASS 'foo'.padEnd() is 'foo'
+PASS 'foo'.padEnd(+0) is 'foo'
+PASS 'foo'.padEnd(-0) is 'foo'
+PASS 'foo'.padEnd(1) is 'foo'
+PASS 'foo'.padEnd(2) is 'foo'
+PASS 'foo'.padEnd(-2) is 'foo'
+PASS 'foo'.padEnd(10) is 'foo       '
+PASS 'foo'.padEnd(10, undefined) is 'foo       '
+PASS 'foo'.padEnd(10, 'x') is 'fooxxxxxxx'
+PASS 'foo'.padEnd(10.5, 'z') is 'foozzzzzzz'
+PASS 'foo'.padEnd(10, 'bar') is 'foobarbarb'
+PASS 'foo'.padEnd(10, '123456789') is 'foo1234567'
+PASS 'foo'.padEnd(999, '') is 'foo'
+PASS ''.padEnd(1, '') is ''
+PASS ''.padEnd(2, 'bar') is 'ba'
+PASS 'x'.padEnd(2, 'bar') is 'xb'
+PASS 'xx'.padEnd(2, 'bar') is 'xx'
+PASS 'xx'.padEnd(Math.PI, 'bar') is 'xxb'
+PASS ''.padEnd(true, 'ABC') is 'A'
+PASS ''.padEnd(false, 'ABC') is ''
+PASS ''.padEnd(null, 'ABC') is ''
+PASS ''.padEnd({}, 'ABC') is ''
+PASS ''.padEnd(NaN, 'ABC') is ''
+PASS 'ABC'.padEnd(10, true) is 'ABCtruetru'
+PASS 'ABC'.padEnd(10, false) is 'ABCfalsefa'
+PASS 'ABC'.padEnd(10, null) is 'ABCnullnul'
+PASS 'ABC'.padEnd(10, {}) is 'ABC[object'
+PASS 'ABC'.padEnd(10, NaN) is 'ABCNaNNaNN'
+PASS "x".padEnd(Infinity, "") did not throw exception.
+PASS "x".padEnd(Infinity, "x") threw exception Error: Out of memory.
+PASS "x".padEnd(0x80000000, "x") threw exception Error: Out of memory.
+PASS "x".padEnd(0xFFFFFFFF, "x") threw exception Error: Out of memory.
+PASS String.prototype.padEnd.call(thisObject, lengthObject, fillObject) is "foo barXXX"
+PASS sideEffects is "ABC"
+PASS String.prototype.padEnd.call(thisObject, lengthObject, fillObject) threw exception ERROR.
+PASS sideEffects is ""
+PASS String.prototype.padEnd.call(thisObject, lengthObject, fillObject) threw exception ERROR.
+PASS sideEffects is "A"
+PASS String.prototype.padEnd.call(thisObject, lengthObject, fillObject) threw exception ERROR.
+PASS sideEffects is "AB"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/string-padend.html (0 => 202966)


--- trunk/LayoutTests/js/string-padend.html	                        (rev 0)
+++ trunk/LayoutTests/js/string-padend.html	2016-07-08 06:25:34 UTC (rev 202966)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="UTF-8">
+  <script src=""
+</head>
+<body>
+  <script src=""
+  <script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/string-padstart-expected.txt (0 => 202966)


--- trunk/LayoutTests/js/string-padstart-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/string-padstart-expected.txt	2016-07-08 06:25:34 UTC (rev 202966)
@@ -0,0 +1,57 @@
+This test checks the String.prototype.padStart.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS String.prototype.padStart.length is 1
+PASS String.prototype.padStart.name is "padStart"
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padStart").configurable is true
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padStart").enumerable is false
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padStart").writable is true
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padStart").get is undefined
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padStart").set is undefined
+PASS Object.getOwnPropertyDescriptor(String.prototype, "padStart").value is String.prototype.padStart
+PASS 'foo'.padStart() is 'foo'
+PASS 'foo'.padStart(+0) is 'foo'
+PASS 'foo'.padStart(-0) is 'foo'
+PASS 'foo'.padStart(1) is 'foo'
+PASS 'foo'.padStart(2) is 'foo'
+PASS 'foo'.padStart(-2) is 'foo'
+PASS 'foo'.padStart(10) is '       foo'
+PASS 'foo'.padStart(10, undefined) is '       foo'
+PASS 'foo'.padStart(10, 'x') is 'xxxxxxxfoo'
+PASS 'foo'.padStart(10.5, 'z') is 'zzzzzzzfoo'
+PASS 'foo'.padStart(10, 'bar') is 'barbarbfoo'
+PASS 'foo'.padStart(10, '123456789') is '1234567foo'
+PASS 'foo'.padStart(999, '') is 'foo'
+PASS ''.padStart(1, '') is ''
+PASS ''.padStart(2, 'bar') is 'ba'
+PASS 'x'.padStart(2, 'bar') is 'bx'
+PASS 'xx'.padStart(2, 'bar') is 'xx'
+PASS 'xx'.padStart(Math.PI, 'bar') is 'bxx'
+PASS ''.padStart(true, 'ABC') is 'A'
+PASS ''.padStart(false, 'ABC') is ''
+PASS ''.padStart(null, 'ABC') is ''
+PASS ''.padStart({}, 'ABC') is ''
+PASS ''.padStart(NaN, 'ABC') is ''
+PASS 'ABC'.padStart(10, true) is 'truetruABC'
+PASS 'ABC'.padStart(10, false) is 'falsefaABC'
+PASS 'ABC'.padStart(10, null) is 'nullnulABC'
+PASS 'ABC'.padStart(10, {}) is '[objectABC'
+PASS 'ABC'.padStart(10, NaN) is 'NaNNaNNABC'
+PASS "x".padStart(Infinity, "") did not throw exception.
+PASS "x".padStart(Infinity, "x") threw exception Error: Out of memory.
+PASS "x".padStart(0x80000000, "x") threw exception Error: Out of memory.
+PASS "x".padStart(0xFFFFFFFF, "x") threw exception Error: Out of memory.
+PASS String.prototype.padStart.call(thisObject, lengthObject, fillObject) is "XXXfoo bar"
+PASS sideEffects is "ABC"
+PASS String.prototype.padStart.call(thisObject, lengthObject, fillObject) threw exception ERROR.
+PASS sideEffects is ""
+PASS String.prototype.padStart.call(thisObject, lengthObject, fillObject) threw exception ERROR.
+PASS sideEffects is "A"
+PASS String.prototype.padStart.call(thisObject, lengthObject, fillObject) threw exception ERROR.
+PASS sideEffects is "AB"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/string-padstart.html (0 => 202966)


--- trunk/LayoutTests/js/string-padstart.html	                        (rev 0)
+++ trunk/LayoutTests/js/string-padstart.html	2016-07-08 06:25:34 UTC (rev 202966)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="UTF-8">
+  <script src=""
+</head>
+<body>
+  <script src=""
+  <script src=""
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (202965 => 202966)


--- trunk/Source/_javascript_Core/ChangeLog	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-07-08 06:25:34 UTC (rev 202966)
@@ -1,3 +1,39 @@
+2016-07-07  Joseph Pecoraro  <[email protected]>
+
+        padStart/padEnd with Infinity produces unexpected result
+        https://bugs.webkit.org/show_bug.cgi?id=159543
+
+        Reviewed by Benjamin Poulain.
+
+        * builtins/GlobalOperations.js:
+        (globalPrivate.toLength):
+        Fix style.
+
+        * builtins/StringPrototype.js:
+        (padStart):
+        (padEnd):
+        After all observable operations, and after empty string has been handled,
+        throw an out of memory error if the resulting string would be greater
+        than the maximum string size.
+
+        * tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js:
+        (shouldThrow): Deleted.
+        * tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js:
+        (shouldThrow):
+        (testMeta):
+        * tests/es6/String.prototype_methods_String.prototype.padEnd.js:
+        (shouldThrow):
+        (TestToLength):
+        (TestMemoryLimits):
+        (TestMeta): Deleted.
+        * tests/es6/String.prototype_methods_String.prototype.padStart.js:
+        (shouldThrow):
+        (TestToLength):
+        (TestMemoryLimits):
+        Replace incorrect shouldThrow(..., errorType) with explicit shouldThrow(..., errorMessage).
+        The old shouldThrow would incorrectly succeed if the expected error type was just "Error".
+        Now we explicitly check the error message.
+
 2016-07-07  Benjamin Poulain  <[email protected]>
 
         [JSC] String.prototype[Symbol.iterator] needs a name

Modified: trunk/Source/_javascript_Core/builtins/GlobalOperations.js (202965 => 202966)


--- trunk/Source/_javascript_Core/builtins/GlobalOperations.js	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/Source/_javascript_Core/builtins/GlobalOperations.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -45,8 +45,7 @@
 
     var length = @toInteger(target);
     // originally Math.min(Math.max(length, 0), maxSafeInteger));
-    return length > 0 ? (length < @MAX_SAFE_INTEGER? length : @MAX_SAFE_INTEGER) : 0;
-
+    return length > 0 ? (length < @MAX_SAFE_INTEGER ? length : @MAX_SAFE_INTEGER) : 0;
 }
 
 @globalPrivate

Modified: trunk/Source/_javascript_Core/builtins/StringPrototype.js (202965 => 202966)


--- trunk/Source/_javascript_Core/builtins/StringPrototype.js	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/Source/_javascript_Core/builtins/StringPrototype.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -138,7 +138,6 @@
 
     var string = @toString(this);
     maxLength = @toLength(maxLength);
-    var fillString = arguments[1];
 
     var stringLength = string.length;
     if (maxLength <= stringLength)
@@ -145,14 +144,18 @@
         return string;
 
     var filler;
-    if (arguments[1] === @undefined)
+    var fillString = arguments[1];
+    if (fillString === @undefined)
         filler = " ";
     else {
-        filler = @toString(arguments[1]);
+        filler = @toString(fillString);
         if (filler === "")
             return string;
     }
 
+    if (maxLength > @MAX_STRING_LENGTH)
+        throw new @Error("Out of memory");
+
     var fillLength = maxLength - stringLength;
     var truncatedStringFiller;
 
@@ -181,14 +184,18 @@
         return string;
 
     var filler;
-    if (arguments[1] === @undefined)
+    var fillString = arguments[1];
+    if (fillString === @undefined)
         filler = " ";
     else {
-        filler = @toString(arguments[1]);
+        filler = @toString(fillString);
         if (filler === "")
             return string;
     }
 
+    if (maxLength > @MAX_STRING_LENGTH)
+        throw new @Error("Out of memory");
+
     var fillLength = maxLength - stringLength;
     var truncatedStringFiller;
 

Modified: trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js (202965 => 202966)


--- trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -7,16 +7,6 @@
         throw new Error('bad value' + msg + ': ' + actual + '. Expected ' + expected);
 }
 
-function shouldThrow(func, errorType) {
-    try {
-        func();
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but did not throw.');
-    } catch (e) {
-        if (e instanceof errorType) return;
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but threw ' + e);
-    }
-}
-
 function shouldBeDataProperty(expected, value, name) {
     if (name === void 0)
         name = '<property descriptor>';

Modified: trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js (202965 => 202966)


--- trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -7,14 +7,19 @@
         throw new Error('bad value' + msg + ': ' + actual + '. Expected ' + expected);
 }
 
-function shouldThrow(func, errorType) {
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
     try {
         func();
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but did not throw.');
     } catch (e) {
-        if (e instanceof errorType) return;
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but threw ' + e);
+        errorThrown = true;
+        error = e;
     }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
 }
 
 function shouldBeDataProperty(expected, value, name) {
@@ -38,13 +43,13 @@
     shouldBe(true, propertyDescriptor.writable);
     shouldBe(true, propertyDescriptor.configurable);
 
-    shouldThrow(() => new Object.getOwnPropertyDescriptors({}), TypeError);
+    shouldThrow(() => new Object.getOwnPropertyDescriptors({}), "TypeError: function is not a constructor (evaluating 'new Object.getOwnPropertyDescriptors({})')");
 })();
 
 (function testToObject() {
-    shouldThrow(() => Object.getOwnPropertyDescriptors(null), TypeError);
-    shouldThrow(() => Object.getOwnPropertyDescriptors(undefined), TypeError);
-    shouldThrow(() => Object.getOwnPropertyDescriptors(), TypeError);
+    shouldThrow(() => Object.getOwnPropertyDescriptors(null), "TypeError: null is not an object (evaluating 'Object.getOwnPropertyDescriptors(null)')");
+    shouldThrow(() => Object.getOwnPropertyDescriptors(undefined), "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptors(undefined)')");
+    shouldThrow(() => Object.getOwnPropertyDescriptors(), "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptors()')");
 })();
 
 (function testPrototypeProperties() {

Modified: trunk/Source/_javascript_Core/tests/es6/String.prototype_methods_String.prototype.padEnd.js (202965 => 202966)


--- trunk/Source/_javascript_Core/tests/es6/String.prototype_methods_String.prototype.padEnd.js	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/Source/_javascript_Core/tests/es6/String.prototype_methods_String.prototype.padEnd.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -7,14 +7,19 @@
         throw new Error('bad value' + msg + ': ' + actual + '. Expected ' + expected);
 }
 
-function shouldThrow(func, errorType) {
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
     try {
         func();
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but did not throw.');
     } catch (e) {
-        if (e instanceof errorType) return;
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but threw ' + e);
+        errorThrown = true;
+        error = e;
     }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
 }
 
 (function TestMeta() {
@@ -31,13 +36,13 @@
     shouldBe(true, descriptor.writable);
     shouldBe(String.prototype.padEnd, descriptor.value);
 
-    shouldThrow(() => new Function(`${String.prototype.padEnd}`), SyntaxError);
+    shouldThrow(() => new Function(`${String.prototype.padEnd}`), "SyntaxError: Unexpected identifier 'code'. Expected either a closing ']' or a ',' following an array element.");
 })();
 
 (function TestRequireObjectCoercible() {
     var padEnd = String.prototype.padEnd;
-    shouldThrow(() => padEnd.call(null, 4, "test"), TypeError);
-    shouldThrow(() => padEnd.call(undefined, 4, "test"), TypeError);
+    shouldThrow(() => padEnd.call(null, 4, "test"), "TypeError: String.prototype.padEnd requires that |this| not be null");
+    shouldThrow(() => padEnd.call(undefined, 4, "test"), "TypeError: String.prototype.padEnd requires that |this| not be undefined");
     shouldBe("123   ", padEnd.call({
         __proto__: null,
         valueOf() { return 123; }
@@ -63,7 +68,7 @@
 })();
 
 (function TestToLength() {
-    shouldThrow(() => "123".padEnd(Symbol("16")), TypeError);
+    shouldThrow(() => "123".padEnd(Symbol("16")), "TypeError: Cannot convert a symbol to a number");
     shouldBe("123", "123".padEnd(-1));
     shouldBe("123", "123".padEnd({ toString() { return -1; } }));
     shouldBe("123", "123".padEnd(-0));
@@ -96,9 +101,9 @@
 })();
 
 (function TestMemoryLimits() {
-    shouldThrow(() => ".".padEnd(0x80000000, "o"), Error);
-    shouldThrow(() => ".".padEnd({ valueOf() { return 0x80000000; } }, "o"), Error);
-    shouldThrow(() => ".".padEnd("0x80000000", "o"), Error);
+    shouldThrow(() => ".".padEnd(0x80000000, "o"), "Error: Out of memory");
+    shouldThrow(() => ".".padEnd({ valueOf() { return 0x80000000; } }, "o"), "Error: Out of memory");
+    shouldThrow(() => ".".padEnd("0x80000000", "o"), "Error: Out of memory");
 })();
 
 (function TestFillerRepetition() {

Modified: trunk/Source/_javascript_Core/tests/es6/String.prototype_methods_String.prototype.padStart.js (202965 => 202966)


--- trunk/Source/_javascript_Core/tests/es6/String.prototype_methods_String.prototype.padStart.js	2016-07-08 06:23:11 UTC (rev 202965)
+++ trunk/Source/_javascript_Core/tests/es6/String.prototype_methods_String.prototype.padStart.js	2016-07-08 06:25:34 UTC (rev 202966)
@@ -7,14 +7,19 @@
         throw new Error('bad value' + msg + ': ' + actual + '. Expected ' + expected);
 }
 
-function shouldThrow(func, errorType) {
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
     try {
         func();
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but did not throw.');
     } catch (e) {
-        if (e instanceof errorType) return;
-        throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but threw ' + e);
+        errorThrown = true;
+        error = e;
     }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
 }
 
 (function TestMeta() {
@@ -31,13 +36,13 @@
     shouldBe(true, descriptor.writable);
     shouldBe(String.prototype.padStart, descriptor.value);
 
-    shouldThrow(() => new Function(`${String.prototype.padStart}`), SyntaxError);
+    shouldThrow(() => new Function(`${String.prototype.padStart}`), "SyntaxError: Unexpected identifier 'code'. Expected either a closing ']' or a ',' following an array element.");
 })();
 
 (function TestRequireObjectCoercible() {
     var padStart = String.prototype.padStart;
-    shouldThrow(() => padStart.call(null, 4, "test"), TypeError);
-    shouldThrow(() => padStart.call(undefined, 4, "test"), TypeError);
+    shouldThrow(() => padStart.call(null, 4, "test"), "TypeError: String.prototype.padStart requires that |this| not be null");
+    shouldThrow(() => padStart.call(undefined, 4, "test"), "TypeError: String.prototype.padStart requires that |this| not be undefined");
     shouldBe("   123", padStart.call({
         __proto__: null,
         valueOf() { return 123; }
@@ -63,7 +68,7 @@
 })();
 
 (function TestToLength() {
-    shouldThrow(() => "123".padStart(Symbol("16")), TypeError);
+    shouldThrow(() => "123".padStart(Symbol("16")), "TypeError: Cannot convert a symbol to a number");
     shouldBe("123", "123".padStart(-1));
     shouldBe("123", "123".padStart({ toString() { return -1; } }));
     shouldBe("123", "123".padStart(-0));
@@ -96,9 +101,9 @@
 })();
 
 (function TestMemoryLimits() {
-    shouldThrow(() => ".".padStart(0x80000000, "o"), Error);
-    shouldThrow(() => ".".padStart({ valueOf() { return 0x80000000; } }, "o"), Error);
-    shouldThrow(() => ".".padStart("0x80000000", "o"), Error);
+    shouldThrow(() => ".".padStart(0x80000000, "o"), "Error: Out of memory");
+    shouldThrow(() => ".".padStart({ valueOf() { return 0x80000000; } }, "o"), "Error: Out of memory");
+    shouldThrow(() => ".".padStart("0x80000000", "o"), "Error: Out of memory");
 })();
 
 (function TestFillerRepetition() {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to