Title: [207377] trunk
- Revision
- 207377
- Author
- sbar...@apple.com
- Date
- 2016-10-15 13:56:24 -0700 (Sat, 15 Oct 2016)
Log Message
Assertion failed under operationToLowerCase with a rope with zero length
https://bugs.webkit.org/show_bug.cgi?id=163314
Reviewed by Mark Lam.
JSTests:
* stress/to-lower-case-intrinsic-on-empty-rope.js: Added.
(assert):
(returnRope.helper):
(returnRope):
(lower):
Source/_javascript_Core:
There are some ways to get JSC to create empty rope strings. ToLowerCase
inside the DFG/FTL goes to the slow path when the argument is a rope.
operationToLowerCase was calling into a WTF string function that
assumed we are passing it a this value that has non-zero length.
However, we were calling it with a string that did have zero length.
To fix this, we make operationToLowerCase return the empty JSString
if it is going to make a string with zero length.
* dfg/DFGOperations.cpp:
* jsc.cpp:
(GlobalObject::finishCreation):
(functionIsRope):
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (207376 => 207377)
--- trunk/JSTests/ChangeLog 2016-10-15 15:04:01 UTC (rev 207376)
+++ trunk/JSTests/ChangeLog 2016-10-15 20:56:24 UTC (rev 207377)
@@ -1,3 +1,16 @@
+2016-10-15 Saam Barati <sbar...@apple.com>
+
+ Assertion failed under operationToLowerCase with a rope with zero length
+ https://bugs.webkit.org/show_bug.cgi?id=163314
+
+ Reviewed by Mark Lam.
+
+ * stress/to-lower-case-intrinsic-on-empty-rope.js: Added.
+ (assert):
+ (returnRope.helper):
+ (returnRope):
+ (lower):
+
2016-10-14 Benjamin Poulain <bpoul...@apple.com>
[JSC] op_negate should with any type
Added: trunk/JSTests/stress/to-lower-case-intrinsic-on-empty-rope.js (0 => 207377)
--- trunk/JSTests/stress/to-lower-case-intrinsic-on-empty-rope.js (rev 0)
+++ trunk/JSTests/stress/to-lower-case-intrinsic-on-empty-rope.js 2016-10-15 20:56:24 UTC (rev 207377)
@@ -0,0 +1,26 @@
+function assert(b) {
+ if (!b)
+ throw new Error("bad!");
+}
+
+function returnRope() {
+ function helper(r, s) {
+ // I'm paranoid about RegExp matching constant folding.
+ return s.match(r)[1];
+ }
+ noInline(helper);
+ return helper(/(b*)fo/, "fo");
+}
+noInline(returnRope);
+
+function lower(a) {
+ return a.toLowerCase();
+}
+noInline(lower);
+
+for (let i = 0; i < 10000; i++) {
+ let rope = returnRope();
+ assert(!rope.length);
+ assert(isRope(rope)); // Keep this test future proofed. If this stops returning a rope, we should try to find another way to return an empty rope.
+ lower(rope);
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (207376 => 207377)
--- trunk/Source/_javascript_Core/ChangeLog 2016-10-15 15:04:01 UTC (rev 207376)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-10-15 20:56:24 UTC (rev 207377)
@@ -1,3 +1,23 @@
+2016-10-15 Saam Barati <sbar...@apple.com>
+
+ Assertion failed under operationToLowerCase with a rope with zero length
+ https://bugs.webkit.org/show_bug.cgi?id=163314
+
+ Reviewed by Mark Lam.
+
+ There are some ways to get JSC to create empty rope strings. ToLowerCase
+ inside the DFG/FTL goes to the slow path when the argument is a rope.
+ operationToLowerCase was calling into a WTF string function that
+ assumed we are passing it a this value that has non-zero length.
+ However, we were calling it with a string that did have zero length.
+ To fix this, we make operationToLowerCase return the empty JSString
+ if it is going to make a string with zero length.
+
+ * dfg/DFGOperations.cpp:
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionIsRope):
+
2016-10-14 Benjamin Poulain <bpoul...@apple.com>
[JSC] op_negate should with any type
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (207376 => 207377)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-10-15 15:04:01 UTC (rev 207376)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-10-15 20:56:24 UTC (rev 207377)
@@ -1523,6 +1523,9 @@
const String& inputString = string->value(exec);
RETURN_IF_EXCEPTION(scope, nullptr);
+ if (!inputString.length())
+ return vm.smallStrings.emptyString();
+
String lowercasedString = inputString.is8Bit() ? inputString.convertToLowercaseWithoutLocaleStartingAtFailingIndex8Bit(failingIndex) : inputString.convertToLowercaseWithoutLocale();
if (lowercasedString.impl() == inputString.impl())
return string;
Modified: trunk/Source/_javascript_Core/jsc.cpp (207376 => 207377)
--- trunk/Source/_javascript_Core/jsc.cpp 2016-10-15 15:04:01 UTC (rev 207376)
+++ trunk/Source/_javascript_Core/jsc.cpp 2016-10-15 20:56:24 UTC (rev 207377)
@@ -789,6 +789,7 @@
static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionGetRandomSeed(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionSetRandomSeed(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionIsRope(ExecState*);
struct Script {
enum class StrictMode {
@@ -1007,6 +1008,7 @@
addFunction(vm, "getRandomSeed", functionGetRandomSeed, 0);
addFunction(vm, "setRandomSeed", functionSetRandomSeed, 1);
+ addFunction(vm, "isRope", functionIsRope, 1);
addFunction(vm, "is32BitPlatform", functionIs32BitPlatform, 0);
@@ -1805,6 +1807,15 @@
return JSValue::encode(jsUndefined());
}
+EncodedJSValue JSC_HOST_CALL functionIsRope(ExecState* exec)
+{
+ JSValue argument = exec->argument(0);
+ if (!argument.isString())
+ return JSValue::encode(jsBoolean(false));
+ const StringImpl* impl = jsCast<JSString*>(argument)->tryGetValueImpl();
+ return JSValue::encode(jsBoolean(!impl));
+}
+
EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
{
Vector<char, 256> line;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes