Title: [225239] trunk
Revision
225239
Author
[email protected]
Date
2017-11-28 13:58:57 -0800 (Tue, 28 Nov 2017)

Log Message

_javascript_ rest function parameter with negative index leads to bad DFG abstract interpretation

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (225238 => 225239)


--- trunk/JSTests/ChangeLog	2017-11-28 21:43:34 UTC (rev 225238)
+++ trunk/JSTests/ChangeLog	2017-11-28 21:58:57 UTC (rev 225239)
@@ -1,3 +1,17 @@
+2017-11-27  JF Bastien  <[email protected]>
+
+        _javascript_ rest function parameter with negative index leads to bad DFG abstract interpretation
+        https://bugs.webkit.org/show_bug.cgi?id=180051
+        <rdar://problem/35614371>
+
+        Reviewed by Saam Barati.
+
+        * stress/rest-parameter-negative.js: Added.
+        (__f_5484):
+        (catch):
+        (__f_5485):
+        (__v_22598.catch):
+
 2017-11-27  Saam Barati  <[email protected]>
 
         Spread can escape when CreateRest does not

Added: trunk/JSTests/stress/rest-parameter-negative.js (0 => 225239)


--- trunk/JSTests/stress/rest-parameter-negative.js	                        (rev 0)
+++ trunk/JSTests/stress/rest-parameter-negative.js	2017-11-28 21:58:57 UTC (rev 225239)
@@ -0,0 +1,21 @@
+function __f_5484(__v_22596) {
+  if (!__v_22596) throw new Error();
+}
+
+try {
+  noInline(__f_5484);
+} catch (e) {}
+
+function __f_5485(...__v_22597) {
+  return __v_22597[-13];
+}
+
+try {
+  noInline(__f_5485);
+} catch (e) {}
+
+for (let __v_22598 = 0; __v_22598 < 10000; __v_22598++) {
+  try {
+    __f_5484(__f_5485(__v_22598) === __v_22598);
+  } catch (e) {}
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (225238 => 225239)


--- trunk/Source/_javascript_Core/ChangeLog	2017-11-28 21:43:34 UTC (rev 225238)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-11-28 21:58:57 UTC (rev 225239)
@@ -1,3 +1,17 @@
+2017-11-27  JF Bastien  <[email protected]>
+
+        _javascript_ rest function parameter with negative index leads to bad DFG abstract interpretation
+        https://bugs.webkit.org/show_bug.cgi?id=180051
+        <rdar://problem/35614371>
+
+        Reviewed by Saam Barati.
+
+        Checking for int32 isn't sufficient when uint32 is expected
+        afterwards. While we're here, also use Checked<>.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+
 2017-11-14  Carlos Garcia Campos  <[email protected]>
 
         Move JSONValues to WTF and convert uses of InspectorValues.h to JSONValues.h

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (225238 => 225239)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2017-11-28 21:43:34 UTC (rev 225238)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2017-11-28 21:58:57 UTC (rev 225239)
@@ -40,6 +40,8 @@
 #include "PutByIdStatus.h"
 #include "StringObject.h"
 
+#include <wtf/CheckedArithmetic.h>
+
 namespace JSC { namespace DFG {
 
 template<typename AbstractStateType>
@@ -1877,25 +1879,29 @@
         JSValue index = forNode(node->child2()).m_value;
         InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
 
-        if (index && index.isInt32()) {
+        if (index && index.isUInt32()) {
             // This pretends to return TOP for accesses that are actually proven out-of-bounds because
             // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
             // paths as unreachable, or to return undefined. We could implement that eventually.
-            
-            unsigned argumentIndex = index.asUInt32() + node->numberOfArgumentsToSkip();
-            if (inlineCallFrame) {
-                if (argumentIndex < inlineCallFrame->argumentCountIncludingThis - 1) {
-                    forNode(node) = m_state.variables().operand(
-                        virtualRegisterForArgument(argumentIndex + 1) + inlineCallFrame->stackOffset);
-                    m_state.setFoundConstants(true);
-                    break;
+
+            Checked<unsigned, RecordOverflow> argumentIndexChecked = index.asUInt32();
+            argumentIndexChecked += node->numberOfArgumentsToSkip();
+            unsigned argumentIndex;
+            if (argumentIndexChecked.safeGet(argumentIndex) != CheckedState::DidOverflow) {
+                if (inlineCallFrame) {
+                    if (argumentIndex < inlineCallFrame->argumentCountIncludingThis - 1) {
+                        forNode(node) = m_state.variables().operand(
+                            virtualRegisterForArgument(argumentIndex + 1) + inlineCallFrame->stackOffset);
+                        m_state.setFoundConstants(true);
+                        break;
+                    }
+                } else {
+                    if (argumentIndex < m_state.variables().numberOfArguments() - 1) {
+                        forNode(node) = m_state.variables().argument(argumentIndex + 1);
+                        m_state.setFoundConstants(true);
+                        break;
+                    }
                 }
-            } else {
-                if (argumentIndex < m_state.variables().numberOfArguments() - 1) {
-                    forNode(node) = m_state.variables().argument(argumentIndex + 1);
-                    m_state.setFoundConstants(true);
-                    break;
-                }
             }
         }
         
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to