Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -1883,7 +1883,8 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
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;
Expand Down
69 changes: 69 additions & 0 deletions test/lit/exec/strings.wast
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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
Expand Down