Changeset 183694 in webkit
- Timestamp:
- May 1, 2015 3:44:30 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r183686 r183694 1 2015-05-01 Jordan Harband <ljharb@gmail.com> 2 3 String#startsWith/endsWith/includes don't handle Infinity position/endPosition args correctly 4 https://bugs.webkit.org/show_bug.cgi?id=144314 5 6 Reviewed by Darin Adler. 7 8 * js/script-tests/string-includes.js: 9 * js/string-includes-expected.txt: 10 1 11 2015-05-01 Martin Robinson <mrobinson@igalia.com> 2 12 -
trunk/LayoutTests/js/script-tests/string-includes.js
r182872 r183694 1 description("This test checks the ES6 string functions startsWith(), endsWith() and includes().");1 description("This test checks the ES6 string functions startsWith(), endsWith(), and includes()."); 2 2 3 3 // Test includes 4 shouldBe("String.prototype.includes.name", "'includes'"); 4 5 shouldBe("String.prototype.includes.length", "1"); 5 6 shouldBe("'foo bar'.includes('bar')", "true"); … … 31 32 shouldBe("'フーバー'.includes('ーバ')", "true"); 32 33 shouldBe("'フーバー'.includes('クー')", "false"); 34 shouldBeFalse("'abc'.includes('a', 'abc'.length)"); 35 shouldBeFalse("'abc'.includes('a', Math.pow(2, 33))"); 36 shouldBeFalse("'abc'.includes('a', Infinity)"); 37 shouldBeTrue("'abc'.includes('ab', -Infinity)"); 38 shouldBeFalse("'abc'.includes('cd', -Infinity)"); 39 shouldBeTrue("'abc'.includes('ab', 0)"); 40 shouldBeFalse("'abc'.includes('cd', 0)"); 33 41 34 42 // Test startsWith 43 shouldBe("String.prototype.startsWith.name", "'startsWith'"); 35 44 shouldBe("String.prototype.startsWith.length", "1"); 36 45 shouldBe("'foo bar'.startsWith('foo')", "true"); … … 61 70 shouldBe("'foo bar'.startsWith('フー')", "false"); 62 71 shouldBe("'foo bar'.startsWith('フー', 1)", "false"); 72 shouldBeFalse("'abc'.startsWith('a', Infinity)"); 73 shouldBeFalse("'abc'.startsWith('a', 1)"); 74 shouldBeTrue("'abc'.startsWith('b', 1)"); 75 shouldBeFalse("'abc'.startsWith('b', 2)"); 76 shouldBeTrue("'abc'.startsWith('c', 2)"); 77 shouldBeFalse("'abc'.startsWith('a', Math.pow(2, 33))"); 63 78 64 79 // Test endsWith 80 shouldBe("String.prototype.endsWith.name", "'endsWith'"); 65 81 shouldBe("String.prototype.endsWith.length", "1"); 66 82 shouldBe("'foo bar'.endsWith('bar')", "true"); … … 94 110 shouldBe("'foo bar'.endsWith('フー')", "false"); 95 111 shouldBe("'foo bar'.endsWith('フー', 3)", "false"); 112 shouldBeTrue("'abc'.endsWith('bc', Infinity)"); 113 shouldBeTrue("'abc'.endsWith('bc', Math.pow(2, 33))"); 114 shouldBeFalse("'abc'.endsWith('a', 0)"); 115 shouldBeTrue("'abc'.endsWith('a', 1)"); 116 shouldBeFalse("'abc'.endsWith('b', 1)"); 117 shouldBeTrue("'abc'.endsWith('b', 2)"); 118 shouldBeFalse("'abc'.endsWith('bc', 2)"); 119 shouldBeTrue("'abc'.endsWith('bc', 3)"); 96 120 97 121 // Call functions with an environment record as 'this'. -
trunk/LayoutTests/js/string-includes-expected.txt
r182872 r183694 1 This test checks the ES6 string functions startsWith(), endsWith() and includes().1 This test checks the ES6 string functions startsWith(), endsWith(), and includes(). 2 2 3 3 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". 4 4 5 5 6 PASS String.prototype.includes.name is 'includes' 6 7 PASS String.prototype.includes.length is 1 7 8 PASS 'foo bar'.includes('bar') is true … … 33 34 PASS 'フーバー'.includes('ーバ') is true 34 35 PASS 'フーバー'.includes('クー') is false 36 PASS 'abc'.includes('a', 'abc'.length) is false 37 PASS 'abc'.includes('a', Math.pow(2, 33)) is false 38 PASS 'abc'.includes('a', Infinity) is false 39 PASS 'abc'.includes('ab', -Infinity) is true 40 PASS 'abc'.includes('cd', -Infinity) is false 41 PASS 'abc'.includes('ab', 0) is true 42 PASS 'abc'.includes('cd', 0) is false 43 PASS String.prototype.startsWith.name is 'startsWith' 35 44 PASS String.prototype.startsWith.length is 1 36 45 PASS 'foo bar'.startsWith('foo') is true … … 61 70 PASS 'foo bar'.startsWith('フー') is false 62 71 PASS 'foo bar'.startsWith('フー', 1) is false 72 PASS 'abc'.startsWith('a', Infinity) is false 73 PASS 'abc'.startsWith('a', 1) is false 74 PASS 'abc'.startsWith('b', 1) is true 75 PASS 'abc'.startsWith('b', 2) is false 76 PASS 'abc'.startsWith('c', 2) is true 77 PASS 'abc'.startsWith('a', Math.pow(2, 33)) is false 78 PASS String.prototype.endsWith.name is 'endsWith' 63 79 PASS String.prototype.endsWith.length is 1 64 80 PASS 'foo bar'.endsWith('bar') is true … … 92 108 PASS 'foo bar'.endsWith('フー') is false 93 109 PASS 'foo bar'.endsWith('フー', 3) is false 110 PASS 'abc'.endsWith('bc', Infinity) is true 111 PASS 'abc'.endsWith('bc', Math.pow(2, 33)) is true 112 PASS 'abc'.endsWith('a', 0) is false 113 PASS 'abc'.endsWith('a', 1) is true 114 PASS 'abc'.endsWith('b', 1) is false 115 PASS 'abc'.endsWith('b', 2) is true 116 PASS 'abc'.endsWith('bc', 2) is false 117 PASS 'abc'.endsWith('bc', 3) is true 94 118 PASS (function() { var f = String.prototype.startsWith; (function() { f('a'); })(); })() threw exception TypeError: Type error. 95 119 PASS (function() { var f = String.prototype.endsWith; (function() { f('a'); })(); })() threw exception TypeError: Type error. -
trunk/Source/JavaScriptCore/ChangeLog
r183692 r183694 1 2015-05-01 Jordan Harband <ljharb@gmail.com> 2 3 String#startsWith/endsWith/includes don't handle Infinity position/endPosition args correctly 4 https://bugs.webkit.org/show_bug.cgi?id=144314 5 6 Reviewed by Darin Adler. 7 8 Fixing handling of Infinity position args, per 9 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.includes 10 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith 11 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith 12 13 * runtime/StringPrototype.cpp: 14 (JSC::clampInt32): 15 (JSC::stringProtoFuncStartsWith): 16 (JSC::stringProtoFuncEndsWith): 17 (JSC::stringProtoFuncIncludes): 18 1 19 2015-05-01 Basile Clement <basile_clement@apple.com> 2 20 -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r183141 r183694 1670 1670 } 1671 1671 1672 static inline unsigned clampAndTruncateToUnsigned(double value, unsigned min, unsigned max) 1673 { 1674 if (value < min) 1675 return min; 1676 if (value > max) 1677 return max; 1678 return static_cast<unsigned>(value); 1679 } 1680 1672 1681 EncodedJSValue JSC_HOST_CALL stringProtoFuncStartsWith(ExecState* exec) 1673 1682 { … … 1688 1697 return JSValue::encode(jsUndefined()); 1689 1698 1690 unsigned start = std::max(0, exec->argument(1).toInt32(exec)); 1691 if (exec->hadException()) 1692 return JSValue::encode(jsUndefined()); 1699 JSValue positionArg = exec->argument(1); 1700 unsigned start = 0; 1701 if (positionArg.isInt32()) 1702 start = std::max(0, positionArg.asInt32()); 1703 else { 1704 unsigned length = stringToSearchIn.length(); 1705 start = clampAndTruncateToUnsigned(positionArg.toInteger(exec), 0, length); 1706 if (exec->hadException()) 1707 return JSValue::encode(jsUndefined()); 1708 } 1693 1709 1694 1710 return JSValue::encode(jsBoolean(stringToSearchIn.hasInfixStartingAt(searchString, start))); … … 1714 1730 1715 1731 unsigned length = stringToSearchIn.length(); 1716 JSValue a1 = exec->argument(1); 1717 int pos = a1.isUndefined() ? length : a1.toInt32(exec); 1718 if (exec->hadException()) 1719 return JSValue::encode(jsUndefined()); 1720 unsigned end = std::min<unsigned>(std::max(pos, 0), length); 1721 1722 return JSValue::encode(jsBoolean(stringToSearchIn.hasInfixEndingAt(searchString, end))); 1732 1733 JSValue endPositionArg = exec->argument(1); 1734 unsigned end = length; 1735 if (endPositionArg.isInt32()) 1736 end = std::max(0, endPositionArg.asInt32()); 1737 else if (!endPositionArg.isUndefined()) { 1738 end = clampAndTruncateToUnsigned(endPositionArg.toInteger(exec), 0, length); 1739 if (exec->hadException()) 1740 return JSValue::encode(jsUndefined()); 1741 } 1742 1743 return JSValue::encode(jsBoolean(stringToSearchIn.hasInfixEndingAt(searchString, std::min(end, length)))); 1723 1744 } 1724 1745 … … 1741 1762 return JSValue::encode(jsUndefined()); 1742 1763 1743 unsigned start = std::max(0, exec->argument(1).toInt32(exec)); 1744 if (exec->hadException()) 1745 return JSValue::encode(jsUndefined()); 1764 JSValue positionArg = exec->argument(1); 1765 unsigned start = 0; 1766 if (positionArg.isInt32()) 1767 start = std::max(0, positionArg.asInt32()); 1768 else { 1769 unsigned length = stringToSearchIn.length(); 1770 start = clampAndTruncateToUnsigned(positionArg.toInteger(exec), 0, length); 1771 if (exec->hadException()) 1772 return JSValue::encode(jsUndefined()); 1773 } 1746 1774 1747 1775 return JSValue::encode(jsBoolean(stringToSearchIn.contains(searchString, true, start)));
Note: See TracChangeset
for help on using the changeset viewer.