diff options
-rw-r--r-- | src/wasm-interpreter.h | 3 | ||||
-rw-r--r-- | test/lit/exec/strings.wast | 69 |
2 files changed, 71 insertions, 1 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 8db33de74..c95f694ef 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1883,7 +1883,8 @@ public: const auto& ptrDataValues = ptrData->values; size_t startVal = start.getSingleValue().getUnsigned(); size_t endVal = end.getSingleValue().getUnsigned(); - if (startVal > ptrDataValues.size() || endVal > ptrDataValues.size()) { + if (startVal > ptrDataValues.size() || endVal > ptrDataValues.size() || + endVal < startVal) { trap("array oob"); } Literals contents; diff --git a/test/lit/exec/strings.wast b/test/lit/exec/strings.wast index 4fb17a9e3..c67436c98 100644 --- a/test/lit/exec/strings.wast +++ b/test/lit/exec/strings.wast @@ -342,6 +342,59 @@ ) ) + ;; CHECK: [fuzz-exec] calling new_oob + ;; CHECK-NEXT: [trap array oob] + (func $new_oob (export "new_oob") (result stringref) + ;; Try to make a string from an array of size 1 that we slice at [1:0], + ;; which is out of bounds due to the ending index (we must trap if the end + ;; is less then the start). + (string.new_wtf16_array + (array.new_default $array16 + (i32.const 1) + ) + (i32.const 1) + (i32.const 0) + ) + ) + + ;; CHECK: [fuzz-exec] calling new_2 + ;; CHECK-NEXT: [fuzz-exec] note result: new_2 => string("") + (func $new_2 (export "new_2") (result stringref) + (string.new_wtf16_array + (array.new_default $array16 + (i32.const 1) + ) + (i32.const 1) + (i32.const 1) ;; this changed, which makes this an in-bounds operation + ;; that emits an empty string + ) + ) + + ;; CHECK: [fuzz-exec] calling new_oob_3 + ;; CHECK-NEXT: [trap array oob] + (func $new_oob_3 (export "new_oob_3") (result stringref) + (string.new_wtf16_array + (array.new_default $array16 + (i32.const 1) + ) + (i32.const 1) + (i32.const 2) ;; this changed, and again we are out of bounds + ) + ) + + ;; CHECK: [fuzz-exec] calling new_4 + ;; CHECK-NEXT: [fuzz-exec] note result: new_4 => string("\u0000") + (func $new_4 (export "new_4") (result stringref) + (string.new_wtf16_array + (array.new_default $array16 + (i32.const 2) ;; this changed, and now we are in bounds, and emit a + ;; string of length 1 (with unicode 0) + ) + (i32.const 1) + (i32.const 2) + ) + ) + ;; CHECK: [fuzz-exec] calling slice-unicode ;; CHECK-NEXT: [fuzz-exec] note result: slice-unicode => string("d\u00a3f") (func $slice-unicode (export "slice-unicode") (result (ref string)) @@ -448,6 +501,18 @@ ;; CHECK: [fuzz-exec] calling new_empty_oob_2 ;; CHECK-NEXT: [trap array oob] +;; CHECK: [fuzz-exec] calling new_oob +;; CHECK-NEXT: [trap array oob] + +;; CHECK: [fuzz-exec] calling new_2 +;; CHECK-NEXT: [fuzz-exec] note result: new_2 => string("") + +;; CHECK: [fuzz-exec] calling new_oob_3 +;; CHECK-NEXT: [trap array oob] + +;; CHECK: [fuzz-exec] calling new_4 +;; CHECK-NEXT: [fuzz-exec] note result: new_4 => string("\u0000") + ;; CHECK: [fuzz-exec] calling slice-unicode ;; CHECK-NEXT: [fuzz-exec] note result: slice-unicode => string("d\u00a3f") @@ -475,9 +540,13 @@ ;; CHECK-NEXT: [fuzz-exec] comparing eq.5 ;; CHECK-NEXT: [fuzz-exec] comparing get_codeunit ;; CHECK-NEXT: [fuzz-exec] comparing get_length +;; CHECK-NEXT: [fuzz-exec] comparing new_2 +;; CHECK-NEXT: [fuzz-exec] comparing new_4 ;; CHECK-NEXT: [fuzz-exec] comparing new_empty ;; CHECK-NEXT: [fuzz-exec] comparing new_empty_oob ;; CHECK-NEXT: [fuzz-exec] comparing new_empty_oob_2 +;; CHECK-NEXT: [fuzz-exec] comparing new_oob +;; CHECK-NEXT: [fuzz-exec] comparing new_oob_3 ;; CHECK-NEXT: [fuzz-exec] comparing new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] comparing slice ;; CHECK-NEXT: [fuzz-exec] comparing slice-big |