Null check ArrayBufferView RefPtr
https://bugs.webkit.org/show_bug.cgi?id=221569

Patch by Rob Buis <rbuis@igalia.com> on 2021-02-27
Reviewed by Ryosuke Niwa.

Source/JavaScriptCore:

Null check ArrayBufferView RefPtr before using it.

* runtime/JSArrayBufferViewInlines.h:
(JSC::JSArrayBufferView::unsharedImpl):

LayoutTests:

Add test to verify oom situation does not result in a crash.

* crypto/crypto-random-values-oom-expected.txt: Added.
* crypto/crypto-random-values-oom.html: Added.
* platform/win/TestExpectations:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@273624 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2c030c9..8229eb9 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2021-02-27  Rob Buis  <rbuis@igalia.com>
+
+        Null check ArrayBufferView RefPtr
+        https://bugs.webkit.org/show_bug.cgi?id=221569
+
+        Reviewed by Ryosuke Niwa.
+
+        Add test to verify oom situation does not result in a crash.
+
+        * crypto/crypto-random-values-oom-expected.txt: Added.
+        * crypto/crypto-random-values-oom.html: Added.
+        * platform/win/TestExpectations:
+
 2021-02-27  Antti Koivisto  <antti@apple.com>
 
         Render tree updates for Text node content mutations should happen during rendering update
diff --git a/LayoutTests/crypto/crypto-random-values-oom-expected.txt b/LayoutTests/crypto/crypto-random-values-oom-expected.txt
new file mode 100644
index 0000000..31ce7de
--- /dev/null
+++ b/LayoutTests/crypto/crypto-random-values-oom-expected.txt
@@ -0,0 +1,11 @@
+Test crypto.getRandomValues behavior in oom situation.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS exceptionString == undefined || exceptionString === "TypeError: Argument 1 ('array') to Crypto.getRandomValues must be an instance of ArrayBufferView" is true
+PASS crypto.getRandomValues didn't crash
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/crypto-random-values-oom.html b/LayoutTests/crypto/crypto-random-values-oom.html
new file mode 100644
index 0000000..68fc206
--- /dev/null
+++ b/LayoutTests/crypto/crypto-random-values-oom.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML><!-- webkit-test-runner [ dumpJSConsoleLogInStdErr=true ] -->
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../resources/js-test.js"></script>
+</head>
+<body>
+<script>
+description("Test crypto.getRandomValues behavior in oom situation.")
+
+let exceptionString = undefined;
+
+function useAllMemory() {
+    const a = [0];
+    a.__proto__ = {};
+    Object.defineProperty(a, 0, {get: foo});
+    Object.defineProperty(a, 80000000, {});
+
+    function foo() {
+        new Uint8Array(a);
+    }
+
+    new Promise(foo);
+    try {
+        for (let i = 0; i < 2**32; i++) {
+          new ArrayBuffer(1000);
+        }
+    } catch {
+    }
+}
+
+useAllMemory();
+try {
+    crypto.getRandomValues(new Uint8Array());
+} catch (e) {
+    gc();
+    exceptionString = e.toString();
+}
+gc();
+shouldBeTrue("exceptionString == undefined || exceptionString === \"TypeError: Argument 1 ('array') to Crypto.getRandomValues must be an instance of ArrayBufferView\"");
+testPassed("crypto.getRandomValues didn't crash");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/platform/win/TestExpectations b/LayoutTests/platform/win/TestExpectations
index 78b0e0e..19f8247 100644
--- a/LayoutTests/platform/win/TestExpectations
+++ b/LayoutTests/platform/win/TestExpectations
@@ -4648,3 +4648,6 @@
 fast/css/parsing-color-mix.html [ Failure ]
 fast/css/parsing-relative-color-syntax.html [ Failure ]
 fast/text/letter-spacing-produces-nan-width.html [ Timeout ]
+
+# https://bugs.webkit.org/show_bug.cgi?id=221569
+crypto/crypto-random-values-oom.html [ Skip ]
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index d9ff9a0..5914478 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,15 @@
+2021-02-27  Rob Buis  <rbuis@igalia.com>
+
+        Null check ArrayBufferView RefPtr
+        https://bugs.webkit.org/show_bug.cgi?id=221569
+
+        Reviewed by Ryosuke Niwa.
+
+        Null check ArrayBufferView RefPtr before using it.
+
+        * runtime/JSArrayBufferViewInlines.h:
+        (JSC::JSArrayBufferView::unsharedImpl):
+
 2021-02-26  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] Avoid creating functions unnecessarily in builtins
diff --git a/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h b/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h
index 984f9a2..5b17105 100644
--- a/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h
+++ b/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h
@@ -76,7 +76,7 @@
 inline RefPtr<ArrayBufferView> JSArrayBufferView::unsharedImpl()
 {
     RefPtr<ArrayBufferView> result = possiblySharedImpl();
-    RELEASE_ASSERT(!result->isShared());
+    RELEASE_ASSERT(!result || !result->isShared());
     return result;
 }