Title: [238433] trunk
Revision
238433
Author
mark....@apple.com
Date
2018-11-21 17:51:33 -0800 (Wed, 21 Nov 2018)

Log Message

Creating a wasm memory that is bigger than the ArrayBuffer limit but smaller than the spec limit should throw OOME not RangeError.
https://bugs.webkit.org/show_bug.cgi?id=191776
<rdar://problem/46152851>

Reviewed by Saam Barati.

JSTests:

* stress/big-wasm-memory-grow-no-max.js:
* stress/big-wasm-memory-grow.js:
* stress/big-wasm-memory.js:
- updated these to expect an OutOfMemoryError.

* wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE-2.js: Added.
(Binary.prototype.emit_u8):
(Binary.prototype.emit_u32v):
(Binary.prototype.emit_header):
(Binary.prototype.emit_section):
(Binary):
(WasmModuleBuilder):
(WasmModuleBuilder.prototype.addMemory):
(WasmModuleBuilder.prototype.toArray):
(WasmModuleBuilder.prototype.toBuffer):
(WasmModuleBuilder.prototype.instantiate):
(catch):
* wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE.js: Added.
(catch):

Source/_javascript_Core:

* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::tryCreate):
- return nullptr if the requested bytes exceed MAX_ARRAY_BUFFER_SIZE.
  The clients will already do a null check and throw an OutOfMemoryError if needed.
(JSC::Wasm::Memory::grow):
- throw OOME if newPageCount.bytes() > MAX_ARRAY_BUFFER_SIZE.
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
- throw OOME if newPageCount.bytes() > MAX_ARRAY_BUFFER_SIZE.

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (238432 => 238433)


--- trunk/JSTests/ChangeLog	2018-11-22 01:27:42 UTC (rev 238432)
+++ trunk/JSTests/ChangeLog	2018-11-22 01:51:33 UTC (rev 238433)
@@ -1,3 +1,31 @@
+2018-11-21  Mark Lam  <mark....@apple.com>
+
+        Creating a wasm memory that is bigger than the ArrayBuffer limit but smaller than the spec limit should throw OOME not RangeError.
+        https://bugs.webkit.org/show_bug.cgi?id=191776
+        <rdar://problem/46152851>
+
+        Reviewed by Saam Barati.
+
+        * stress/big-wasm-memory-grow-no-max.js:
+        * stress/big-wasm-memory-grow.js:
+        * stress/big-wasm-memory.js:
+        - updated these to expect an OutOfMemoryError.
+
+        * wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE-2.js: Added.
+        (Binary.prototype.emit_u8):
+        (Binary.prototype.emit_u32v):
+        (Binary.prototype.emit_header):
+        (Binary.prototype.emit_section):
+        (Binary):
+        (WasmModuleBuilder):
+        (WasmModuleBuilder.prototype.addMemory):
+        (WasmModuleBuilder.prototype.toArray):
+        (WasmModuleBuilder.prototype.toBuffer):
+        (WasmModuleBuilder.prototype.instantiate):
+        (catch):
+        * wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE.js: Added.
+        (catch):
+
 2018-11-21  Caio Lima  <ticaiol...@gmail.com>
 
         [BigInt] JSBigInt::createWithLength should throw when length is greater than JSBigInt::maxLength

Modified: trunk/JSTests/stress/big-wasm-memory-grow-no-max.js (238432 => 238433)


--- trunk/JSTests/stress/big-wasm-memory-grow-no-max.js	2018-11-22 01:27:42 UTC (rev 238432)
+++ trunk/JSTests/stress/big-wasm-memory-grow-no-max.js	2018-11-22 01:51:33 UTC (rev 238433)
@@ -26,7 +26,7 @@
         throw "Error: bad result at end: " + result;
     ok = true;
 } catch (e) {
-    if (e.toString() != "RangeError: WebAssembly.Memory.grow expects the grown size to be a valid page count")
+    if (e.toString() != "Error: Out of memory")
         throw e;
 }
 

Modified: trunk/JSTests/stress/big-wasm-memory-grow.js (238432 => 238433)


--- trunk/JSTests/stress/big-wasm-memory-grow.js	2018-11-22 01:27:42 UTC (rev 238432)
+++ trunk/JSTests/stress/big-wasm-memory-grow.js	2018-11-22 01:51:33 UTC (rev 238433)
@@ -26,7 +26,7 @@
         throw "Error: bad result at end: " + result;
     ok = true;
 } catch (e) {
-    if (e.toString() != "RangeError: WebAssembly.Memory.grow expects the grown size to be a valid page count")
+    if (e.toString() != "Error: Out of memory")
         throw e;
 }
 

Modified: trunk/JSTests/stress/big-wasm-memory.js (238432 => 238433)


--- trunk/JSTests/stress/big-wasm-memory.js	2018-11-22 01:27:42 UTC (rev 238432)
+++ trunk/JSTests/stress/big-wasm-memory.js	2018-11-22 01:51:33 UTC (rev 238433)
@@ -24,7 +24,7 @@
         throw "Error: bad result at end: " + result;
     ok = true;
 } catch (e) {
-    if (e.toString() != "RangeError: WebAssembly.Memory 'initial' page count is too large")
+    if (e.toString() != "Error: Out of memory")
         throw e;
 }
 

Added: trunk/JSTests/wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE-2.js (0 => 238433)


--- trunk/JSTests/wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE-2.js	                        (rev 0)
+++ trunk/JSTests/wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE-2.js	2018-11-22 01:51:33 UTC (rev 238433)
@@ -0,0 +1,88 @@
+var kWasmH0 = 0;
+var kWasmH1 = 0x61;
+var kWasmH2 = 0x73;
+var kWasmH3 = 0x6d;
+var kWasmV0 = 0x1;
+var kWasmV1 = 0;
+var kWasmV2 = 0;
+var kWasmV3 = 0;
+let kMemorySectionCode = 5;
+
+class Binary extends Array {
+    emit_u8(val) {
+        this.push(val);
+    }
+    emit_u32v(val) {
+        while (true) {
+            let v = val & 0xff;
+            val = val >>> 7;
+            if (val == 0) {
+                this.push(v);
+                break;
+            }
+            this.push(v | 0x80);
+        }
+    }
+
+    emit_header() {
+        this.push(kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2, kWasmV3);
+    }
+    emit_section(section_code, content_generator) {
+        this.emit_u8(section_code);
+        const section = new Binary();
+        content_generator(section);
+        this.emit_u32v(section.length);
+        for (let b of section)
+            this.push(b);
+    }
+}
+
+class WasmModuleBuilder {
+    constructor() { }
+    addMemory(min) {
+        this.memory = { min: min };
+    }
+    toArray() {
+        let binary = new Binary();
+        let wasm = this;
+        binary.emit_header();
+        binary.emit_section(kMemorySectionCode, section => {
+            section.emit_u8(1);
+            const is_shared = wasm.memory.shared !== undefined;
+            if (is_shared) {
+            } else {
+                section.emit_u8();
+            }
+            section.emit_u32v(wasm.memory.min);
+        });
+        return binary;
+    }
+    toBuffer() {
+        let bytes = this.toArray();
+        let buffer = new ArrayBuffer(bytes.length);
+        let view = new Uint8Array(buffer);
+        for (let i = 0; i < bytes.length; i++) {
+            let val = bytes[i];
+            view[i] = val | 0;
+        }
+        return buffer;
+    }
+    instantiate() {
+        let module = new WebAssembly.Module(this.toBuffer());
+        let instance = new WebAssembly.Instance(module);
+    }
+}
+
+var exception;
+try {
+    var module = new WasmModuleBuilder();
+    module.addMemory(32768);
+    module.instantiate();
+} catch (e) {
+    exception = e;
+}
+
+if (exception != "Error: Out of memory") {
+    print(exception);
+    throw "FAILED";
+}

Added: trunk/JSTests/wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE.js (0 => 238433)


--- trunk/JSTests/wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE.js	                        (rev 0)
+++ trunk/JSTests/wasm/regress/wasm-memory-requested-more-than-MAX_ARRAY_BUFFER_SIZE.js	2018-11-22 01:51:33 UTC (rev 238433)
@@ -0,0 +1,10 @@
+var exception;
+
+try {
+    new WebAssembly.Memory({ initial: 0x8000, maximum: 0x8000 }).buffer;
+} catch (e) {
+    exception = e;
+}
+
+if (exception != "Error: Out of memory")
+    throw "FAILED";

Modified: trunk/Source/_javascript_Core/ChangeLog (238432 => 238433)


--- trunk/Source/_javascript_Core/ChangeLog	2018-11-22 01:27:42 UTC (rev 238432)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-11-22 01:51:33 UTC (rev 238433)
@@ -1,3 +1,21 @@
+2018-11-21  Mark Lam  <mark....@apple.com>
+
+        Creating a wasm memory that is bigger than the ArrayBuffer limit but smaller than the spec limit should throw OOME not RangeError.
+        https://bugs.webkit.org/show_bug.cgi?id=191776
+        <rdar://problem/46152851>
+
+        Reviewed by Saam Barati.
+
+        * wasm/WasmMemory.cpp:
+        (JSC::Wasm::Memory::tryCreate):
+        - return nullptr if the requested bytes exceed MAX_ARRAY_BUFFER_SIZE.
+          The clients will already do a null check and throw an OutOfMemoryError if needed.
+        (JSC::Wasm::Memory::grow):
+        - throw OOME if newPageCount.bytes() > MAX_ARRAY_BUFFER_SIZE.
+        * wasm/js/WebAssemblyMemoryConstructor.cpp:
+        (JSC::constructJSWebAssemblyMemory):
+        - throw OOME if newPageCount.bytes() > MAX_ARRAY_BUFFER_SIZE.
+
 2018-11-21  Caio Lima  <ticaiol...@gmail.com>
 
         [BigInt] JSBigInt::createWithLength should throw when length is greater than JSBigInt::maxLength

Modified: trunk/Source/_javascript_Core/wasm/WasmMemory.cpp (238432 => 238433)


--- trunk/Source/_javascript_Core/wasm/WasmMemory.cpp	2018-11-22 01:27:42 UTC (rev 238432)
+++ trunk/Source/_javascript_Core/wasm/WasmMemory.cpp	2018-11-22 01:51:33 UTC (rev 238433)
@@ -282,7 +282,8 @@
     const size_t initialBytes = initial.bytes();
     const size_t maximumBytes = maximum ? maximum.bytes() : 0;
 
-    RELEASE_ASSERT(initialBytes <= MAX_ARRAY_BUFFER_SIZE);
+    if (initialBytes > MAX_ARRAY_BUFFER_SIZE)
+        return nullptr; // Client will throw OOMError.
 
     if (maximum && !maximumBytes) {
         // User specified a zero maximum, initial size must also be zero.
@@ -374,11 +375,10 @@
         return makeUnexpected(GrowFailReason::InvalidDelta);
     
     const Wasm::PageCount newPageCount = oldPageCount + delta;
-    // FIXME: Creating a wasm memory that is bigger than the ArrayBuffer limit but smaller than the spec limit should throw
-    // OOME not RangeError
-    // https://bugs.webkit.org/show_bug.cgi?id=191776
-    if (!newPageCount || !newPageCount.isValid() || newPageCount.bytes() >= MAX_ARRAY_BUFFER_SIZE)
+    if (!newPageCount || !newPageCount.isValid())
         return makeUnexpected(GrowFailReason::InvalidGrowSize);
+    if (newPageCount.bytes() > MAX_ARRAY_BUFFER_SIZE)
+        return makeUnexpected(GrowFailReason::OutOfMemory);
 
     auto success = [&] () {
         m_growSuccessCallback(GrowSuccessTag, oldPageCount, newPageCount);

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyMemoryConstructor.cpp (238432 => 238433)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyMemoryConstructor.cpp	2018-11-22 01:27:42 UTC (rev 238432)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyMemoryConstructor.cpp	2018-11-22 01:51:33 UTC (rev 238433)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -70,11 +70,10 @@
         RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
         uint32_t size = toNonWrappingUint32(exec, minSizeValue);
         RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-        // FIXME: Creating a wasm memory that is bigger than the ArrayBuffer limit but smaller than the spec limit should throw
-        // OOME not RangeError
-        // https://bugs.webkit.org/show_bug.cgi?id=191776
-        if (!Wasm::PageCount::isValid(size) || Wasm::PageCount(size).bytes() >= MAX_ARRAY_BUFFER_SIZE)
+        if (!Wasm::PageCount::isValid(size))
             return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, "WebAssembly.Memory 'initial' page count is too large"_s)));
+        if (Wasm::PageCount(size).bytes() > MAX_ARRAY_BUFFER_SIZE)
+            return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
         initialPageCount = Wasm::PageCount(size);
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to