Title: [239355] trunk
Revision
239355
Author
[email protected]
Date
2018-12-18 14:24:33 -0800 (Tue, 18 Dec 2018)

Log Message

JSON.stringify() should throw OOM on StringBuilder overflows.
https://bugs.webkit.org/show_bug.cgi?id=192822
<rdar://problem/46670577>

Reviewed by Saam Barati.

JSTests:

* stress/json-stringify-string-builder-overflow.js: Added.

Source/_javascript_Core:

* runtime/JSONObject.cpp:
(JSC::Stringifier::stringify):
(JSC::Stringifier::appendStringifiedValue):
(JSC::Stringifier::Holder::appendNextProperty):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (239354 => 239355)


--- trunk/JSTests/ChangeLog	2018-12-18 22:14:20 UTC (rev 239354)
+++ trunk/JSTests/ChangeLog	2018-12-18 22:24:33 UTC (rev 239355)
@@ -1,3 +1,13 @@
+2018-12-18  Mark Lam  <[email protected]>
+
+        JSON.stringify() should throw OOM on StringBuilder overflows.
+        https://bugs.webkit.org/show_bug.cgi?id=192822
+        <rdar://problem/46670577>
+
+        Reviewed by Saam Barati.
+
+        * stress/json-stringify-string-builder-overflow.js: Added.
+
 2018-12-18  Ross Kirsling  <[email protected]>
 
         Redeclaration of var over let/const/class should be a syntax error.

Added: trunk/JSTests/stress/json-stringify-string-builder-overflow.js (0 => 239355)


--- trunk/JSTests/stress/json-stringify-string-builder-overflow.js	                        (rev 0)
+++ trunk/JSTests/stress/json-stringify-string-builder-overflow.js	2018-12-18 22:24:33 UTC (rev 239355)
@@ -0,0 +1,29 @@
+//@ slow
+//@ skip if $architecture != "arm64" and $architecture != "x86-64"
+
+var exception;
+try {
+    var str = JSON.stringify({
+        'a1': {
+            'a2': {
+                'a3': {
+                    'a4': {
+                        'a5': {
+                            'a6': 'AAAAAAAAAA'
+                        }
+                    }
+                }
+            }
+        }
+    }, function (key, value) {
+        var val = {
+            'A': true,
+        };
+        return val;
+    }, 1);
+} catch (e) {
+    exception = e;
+}
+
+if (exception != "Error: Out of memory")
+    throw "FAILED";

Modified: trunk/Source/_javascript_Core/ChangeLog (239354 => 239355)


--- trunk/Source/_javascript_Core/ChangeLog	2018-12-18 22:14:20 UTC (rev 239354)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-12-18 22:24:33 UTC (rev 239355)
@@ -1,3 +1,16 @@
+2018-12-18  Mark Lam  <[email protected]>
+
+        JSON.stringify() should throw OOM on StringBuilder overflows.
+        https://bugs.webkit.org/show_bug.cgi?id=192822
+        <rdar://problem/46670577>
+
+        Reviewed by Saam Barati.
+
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::stringify):
+        (JSC::Stringifier::appendStringifiedValue):
+        (JSC::Stringifier::Holder::appendNextProperty):
+
 2018-12-18  Ross Kirsling  <[email protected]>
 
         Redeclaration of var over let/const/class should be a syntax error.

Modified: trunk/Source/_javascript_Core/runtime/JSONObject.cpp (239354 => 239355)


--- trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2018-12-18 22:14:20 UTC (rev 239354)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2018-12-18 22:24:33 UTC (rev 239355)
@@ -269,7 +269,7 @@
     JSObject* object = nullptr;
     if (isCallableReplacer()) {
         object = constructEmptyObject(m_exec);
-        RETURN_IF_EXCEPTION(scope, jsNull());
+        RETURN_IF_EXCEPTION(scope, jsUndefined());
         object->putDirect(vm, vm.propertyNames->emptyIdentifier, value);
     }
 
@@ -276,10 +276,13 @@
     StringBuilder result(StringBuilder::OverflowHandler::RecordOverflow);
     Holder root(Holder::RootHolder, object);
     auto stringifyResult = appendStringifiedValue(result, value, root, emptyPropertyName);
-    EXCEPTION_ASSERT(!scope.exception() || (stringifyResult != StringifySucceeded));
+    RETURN_IF_EXCEPTION(scope, jsUndefined());
+    if (UNLIKELY(result.hasOverflowed())) {
+        throwOutOfMemoryError(m_exec, scope);
+        return jsUndefined();
+    }
     if (UNLIKELY(stringifyResult != StringifySucceeded))
         return jsUndefined();
-
     RELEASE_AND_RETURN(scope, jsString(m_exec, result.toString()));
 }
 
@@ -359,10 +362,6 @@
         const String& string = asString(value)->value(m_exec);
         RETURN_IF_EXCEPTION(scope, StringifyFailed);
         builder.appendQuotedJSONString(string);
-        if (UNLIKELY(builder.hasOverflowed())) {
-            throwOutOfMemoryError(m_exec, scope);
-            return StringifyFailed;
-        }
         return StringifySucceeded;
     }
 
@@ -391,6 +390,9 @@
         return StringifyFailedDueToUndefinedOrSymbolValue;
     }
 
+    if (UNLIKELY(builder.hasOverflowed()))
+        return StringifyFailed;
+
     // Handle cycle detection, and put the holder on the stack.
     for (unsigned i = 0; i < m_holderStack.size(); i++) {
         if (m_holderStack[i].object() == object) {
@@ -410,6 +412,8 @@
         while (m_holderStack.last().appendNextProperty(*this, builder))
             RETURN_IF_EXCEPTION(scope, StringifyFailed);
         RETURN_IF_EXCEPTION(scope, StringifyFailed);
+        if (UNLIKELY(builder.hasOverflowed()))
+            return StringifyFailed;
         m_holderStack.removeLast();
         m_objectStack.removeLast();
     } while (!m_holderStack.isEmpty());
@@ -493,6 +497,8 @@
         }
         stringifier.indent();
     }
+    if (UNLIKELY(builder.hasOverflowed()))
+        return false;
 
     // Last time through, finish up and return false.
     if (m_index == m_size) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to