Bug 1333011: wasm: tweak segment validation for zero-sized segments; r=luke
authorBenjamin Bouvier <benj@benj.me>
Mon, 23 Jan 2017 14:41:03 +0100
changeset 330763 dc1db518e229391fc1852202c6ce31057d1e0643
parent 330762 5988b2c740a45e221cc19537822477d72ce92452
child 330764 7de92df120488e13bd4315e1790796d2eb8f7af4
push id86070
push userbbouvier@mozilla.com
push dateTue, 24 Jan 2017 10:11:07 +0000
treeherdermozilla-inbound@7de92df12048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1333011
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1333011: wasm: tweak segment validation for zero-sized segments; r=luke MozReview-Commit-ID: IWFntgHAGy0
js/src/jit-test/tests/wasm/import-export.js
js/src/jit-test/tests/wasm/spec/memory.wast
js/src/jit-test/tests/wasm/tables.js
js/src/wasm/WasmModule.cpp
--- a/js/src/jit-test/tests/wasm/import-export.js
+++ b/js/src/jit-test/tests/wasm/import-export.js
@@ -458,17 +458,17 @@ var m = new Module(wasmTextToBinary(`
 `));
 assertErrorMessage(() => new Instance(m), LinkError, /data segment does not fit/);
 
 var m = new Module(wasmTextToBinary(`
     (module
         (memory 0)
         (data (i32.const 0x10001) ""))
 `));
-assertEq(new Instance(m) instanceof Instance, true);
+assertErrorMessage(() => new Instance(m), LinkError, /data segment does not fit/);
 
 // Errors during segment initialization do not have observable effects
 // and are checked against the actual memory/table length, not the declared
 // initial length.
 
 var m = new Module(wasmTextToBinary(`
     (module
         (import "a" "mem" (memory 1))
--- a/js/src/jit-test/tests/wasm/spec/memory.wast
+++ b/js/src/jit-test/tests/wasm/spec/memory.wast
@@ -74,31 +74,43 @@
 ;;   "constant expression required"
 ;; )
 
 (assert_unlinkable
   (module (memory 0 0) (data (i32.const 0) "a"))
   "data segment does not fit"
 )
 (assert_unlinkable
+  (module (memory 0 1) (data (i32.const 0) "a"))
+  "data segment does not fit"
+)
+(assert_unlinkable
   (module (memory 1 2) (data (i32.const 0) "a") (data (i32.const 98304) "b"))
   "data segment does not fit"
 )
+(assert_unlinkable
+  (module (memory 0 0) (data (i32.const 1) ""))
+  "data segment does not fit"
+)
+(assert_unlinkable
+  (module (memory 1) (data (i32.const 0x12000) ""))
+  "data segment does not fit"
+)
 ;; This seems to cause a time-out on Travis.
 (;assert_unlinkable
   (module (memory 0x10000) (data (i32.const 0xffffffff) "ab"))
   ""  ;; either out of memory or segment does not fit
 ;)
 (assert_unlinkable
   (module (global (import "spectest" "global") i32) (memory 0) (data (get_global 0) "a"))
   "data segment does not fit"
 )
 
 (module (memory 0 0) (data (i32.const 0) ""))
-(module (memory 0 0) (data (i32.const 1) ""))
+(module (memory 1 1) (data (i32.const 0x10000) ""))
 (module (memory 1 2) (data (i32.const 0) "abc") (data (i32.const 0) "def"))
 (module (memory 1 2) (data (i32.const 3) "ab") (data (i32.const 0) "de"))
 (module
   (memory 1 2)
   (data (i32.const 0) "a") (data (i32.const 2) "b") (data (i32.const 1) "c")
 )
 
 (assert_invalid
--- a/js/src/jit-test/tests/wasm/tables.js
+++ b/js/src/jit-test/tests/wasm/tables.js
@@ -11,17 +11,17 @@ var callee = i => `(func $f${i} (result 
 
 wasmFailValidateText(`(module (elem (i32.const 0) $f0) ${callee(0)})`, /table index out of range/);
 wasmFailValidateText(`(module (table 10 anyfunc) (elem (i32.const 0) 0))`, /table element out of range/);
 wasmFailValidateText(`(module (table 10 anyfunc) (func) (elem (i32.const 0) 0 1))`, /table element out of range/);
 wasmFailValidateText(`(module (table 10 anyfunc) (func) (elem (f32.const 0) 0) ${callee(0)})`, /type mismatch/);
 
 assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 10) $f0) ${callee(0)})`), LinkError, /elem segment does not fit/);
 assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 8) $f0 $f0 $f0) ${callee(0)})`), LinkError, /elem segment does not fit/);
-wasmEvalText(`(module (table 0 anyfunc) (func) (elem (i32.const 0x10001)))`);
+assertErrorMessage(() => wasmEvalText(`(module (table 0 anyfunc) (func) (elem (i32.const 0x10001)))`), LinkError, /elem segment does not fit/);
 
 assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (get_global 0) $f0) ${callee(0)})`, {globals:{a:10}}), LinkError, /elem segment does not fit/);
 assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (get_global 0) $f0 $f0 $f0) ${callee(0)})`, {globals:{a:8}}), LinkError, /elem segment does not fit/);
 
 assertEq(new Module(wasmTextToBinary(`(module (table 10 anyfunc) (elem (i32.const 1) $f0 $f0) (elem (i32.const 0) $f0) ${callee(0)})`)) instanceof Module, true);
 assertEq(new Module(wasmTextToBinary(`(module (table 10 anyfunc) (elem (i32.const 1) $f0 $f0) (elem (i32.const 2) $f0) ${callee(0)})`)) instanceof Module, true);
 wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (i32.const 1) $f0 $f0) (elem (get_global 0) $f0) ${callee(0)})`, {globals:{a:0}});
 wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (get_global 0) $f0 $f0) (elem (i32.const 2) $f0) ${callee(0)})`, {globals:{a:1}});
--- a/js/src/wasm/WasmModule.cpp
+++ b/js/src/wasm/WasmModule.cpp
@@ -484,34 +484,29 @@ Module::initSegments(JSContext* cx,
     Instance& instance = instanceObj->instance();
     const SharedTableVector& tables = instance.tables();
 
     // Perform all error checks up front so that this function does not perform
     // partial initialization if an error is reported.
 
     for (const ElemSegment& seg : elemSegments_) {
         uint32_t numElems = seg.elemCodeRangeIndices.length();
-        if (!numElems)
-            continue;
 
         uint32_t tableLength = tables[seg.tableIndex]->length();
         uint32_t offset = EvaluateInitExpr(globalImports, seg.offset);
 
         if (offset > tableLength || tableLength - offset < numElems) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_FIT,
                                       "elem", "table");
             return false;
         }
     }
 
     if (memoryObj) {
         for (const DataSegment& seg : dataSegments_) {
-            if (!seg.length)
-                continue;
-
             uint32_t memoryLength = memoryObj->buffer().byteLength();
             uint32_t offset = EvaluateInitExpr(globalImports, seg.offset);
 
             if (offset > memoryLength || memoryLength - offset < seg.length) {
                 JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_FIT,
                                           "data", "memory");
                 return false;
             }