Null pointer dereference in WTF::RefPtr<WTF::StringImpl>::operator!() under slow_path_get_direct_pname
https://bugs.webkit.org/show_bug.cgi?id=171801
Reviewed by Michael Saboff.
JSTests:
These tests used to crash. The prefix and postfix tests cover different paths, except
postfix-ignored goes down the same path as prefix due to an optimization.
* stress/for-in-postfix-ignored-index.js: Added.
(foo):
* stress/for-in-postfix-index.js: Added.
(foo):
* stress/for-in-prefix-index.js: Added.
(foo):
Source/JavaScriptCore:
This was a goofy oversight. The for-in optimization relies on the bytecode generator
to detect when the loop's index variable gets mutated. We forgot to have the hooks for
detecting this in prefix and postfix operations (++i and i++).
* bytecompiler/NodesCodegen.cpp:
(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@216593 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index c149918..860e829 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,3 +1,20 @@
+2017-05-10 Filip Pizlo <fpizlo@apple.com>
+
+ Null pointer dereference in WTF::RefPtr<WTF::StringImpl>::operator!() under slow_path_get_direct_pname
+ https://bugs.webkit.org/show_bug.cgi?id=171801
+
+ Reviewed by Michael Saboff.
+
+ These tests used to crash. The prefix and postfix tests cover different paths, except
+ postfix-ignored goes down the same path as prefix due to an optimization.
+
+ * stress/for-in-postfix-ignored-index.js: Added.
+ (foo):
+ * stress/for-in-postfix-index.js: Added.
+ (foo):
+ * stress/for-in-prefix-index.js: Added.
+ (foo):
+
2017-05-08 Mark Lam <mark.lam@apple.com>
op_throw_static_error's use of its first operand should be reflected in DFG BytecodeUseDef as well.
diff --git a/JSTests/stress/for-in-postfix-ignored-index.js b/JSTests/stress/for-in-postfix-ignored-index.js
new file mode 100644
index 0000000..b7947ea
--- /dev/null
+++ b/JSTests/stress/for-in-postfix-ignored-index.js
@@ -0,0 +1,14 @@
+//@ runDefault
+
+function foo(o) {
+ var result = 0;
+ for (var s in o) {
+ s++;
+ result += o[s];
+ }
+ return result;
+}
+
+var result = foo({f:42});
+if ("" + result != "NaN")
+ throw "Error: bad result: " + result;
diff --git a/JSTests/stress/for-in-postfix-index.js b/JSTests/stress/for-in-postfix-index.js
new file mode 100644
index 0000000..0d59240
--- /dev/null
+++ b/JSTests/stress/for-in-postfix-index.js
@@ -0,0 +1,15 @@
+//@ runDefault
+
+function foo(o) {
+ var result = 0;
+ for (var s in o) {
+ var tmp = s++;
+ result += o[s];
+ result += tmp;
+ }
+ return result;
+}
+
+var result = foo({f:42});
+if ("" + result != "NaN")
+ throw "Error: bad result: " + result;
diff --git a/JSTests/stress/for-in-prefix-index.js b/JSTests/stress/for-in-prefix-index.js
new file mode 100644
index 0000000..4f700fd
--- /dev/null
+++ b/JSTests/stress/for-in-prefix-index.js
@@ -0,0 +1,12 @@
+//@ runDefault
+
+function foo(o) {
+ var result = 0;
+ for (var s in o)
+ result += o[--s];
+ return result;
+}
+
+var result = foo({f:42});
+if ("" + result != "NaN")
+ throw "Error: bad result: " + result;
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index ada621e..d1c9f50 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,18 @@
+2017-05-10 Filip Pizlo <fpizlo@apple.com>
+
+ Null pointer dereference in WTF::RefPtr<WTF::StringImpl>::operator!() under slow_path_get_direct_pname
+ https://bugs.webkit.org/show_bug.cgi?id=171801
+
+ Reviewed by Michael Saboff.
+
+ This was a goofy oversight. The for-in optimization relies on the bytecode generator
+ to detect when the loop's index variable gets mutated. We forgot to have the hooks for
+ detecting this in prefix and postfix operations (++i and i++).
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve):
+
2017-05-10 Michael Catanzaro <mcatanzaro@igalia.com>
[GTK] -Wmissing-field-initializers triggered by RemoteInspectorServer.cpp:128
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index f3e5557..6ad5794 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -1412,6 +1412,7 @@
generator.emitReadOnlyExceptionIfNeeded(var);
localReg = generator.emitMove(generator.tempDestination(dst), local);
}
+ generator.invalidateForInContextForLocal(local);
RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
return oldValue.get();
@@ -1624,6 +1625,7 @@
generator.emitReadOnlyExceptionIfNeeded(var);
localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
} else if (generator.vm()->typeProfiler()) {
+ generator.invalidateForInContextForLocal(local);
RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
generator.emitMove(tempDst.get(), localReg.get());
emitIncOrDec(generator, tempDst.get(), m_operator);
@@ -1631,6 +1633,7 @@
generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
return generator.moveToDestinationIfNeeded(dst, tempDst.get());
}
+ generator.invalidateForInContextForLocal(local);
emitIncOrDec(generator, localReg.get(), m_operator);
return generator.moveToDestinationIfNeeded(dst, localReg.get());
}