diff options
author | Alon Zakai <azakai@google.com> | 2024-03-21 10:07:12 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-21 10:07:12 -0700 |
commit | b1535dac8f544c5000c136d696738a27fc931660 (patch) | |
tree | 9fdf54a2135198b1d2068a697554e1136f951291 | |
parent | 32e7f19f430a0f3c5c66d15333c0956de1e4615e (diff) | |
download | binaryen-b1535dac8f544c5000c136d696738a27fc931660.tar.gz binaryen-b1535dac8f544c5000c136d696738a27fc931660.tar.bz2 binaryen-b1535dac8f544c5000c136d696738a27fc931660.zip |
[Strings] Fix StringSlice end computation (#6414)
Like JS string slicing, if the end index is out of bounds that is fine, we clamp to the end.
This also matches the behavior in V8 and the spec.
-rw-r--r-- | src/wasm-interpreter.h | 5 | ||||
-rw-r--r-- | test/lit/exec/strings.wast | 15 |
2 files changed, 17 insertions, 3 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 36542e6ed..1e0cf3ed0 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1986,6 +1986,7 @@ public: if (ref.breaking()) { return ref; } + // TODO: "WTF-16 position treatment", as in stringview_wtf16.slice? Flow ptr = visit(curr->ptr); if (ptr.breaking()) { return ptr; @@ -2173,9 +2174,7 @@ public: auto& refValues = refData->values; auto startVal = start.getSingleValue().getUnsigned(); auto endVal = end.getSingleValue().getUnsigned(); - if (endVal > refValues.size()) { - trap("array oob"); - } + endVal = std::min<size_t>(endVal, refValues.size()); if (hasNonAsciiUpTo(refValues, endVal)) { return Flow(NONCONSTANT_FLOW); } diff --git a/test/lit/exec/strings.wast b/test/lit/exec/strings.wast index 5ff8ce47a..341dd968b 100644 --- a/test/lit/exec/strings.wast +++ b/test/lit/exec/strings.wast @@ -255,6 +255,17 @@ (i32.const 6) ) ) + + ;; CHECK: [fuzz-exec] calling slice-big + ;; CHECK-NEXT: [fuzz-exec] note result: slice-big => string("defgh") + (func $slice-big (export "slice-big") (result (ref string)) + ;; Slicing [3:huge unsigned value] leads to slicing til the end: "defgh". + (stringview_wtf16.slice + (string.const "abcdefgh") + (i32.const 3) + (i32.const -1) + ) + ) ) ;; CHECK: [fuzz-exec] calling new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] note result: new_wtf16_array => string("ello") @@ -323,6 +334,9 @@ ;; CHECK: [fuzz-exec] calling slice ;; CHECK-NEXT: [fuzz-exec] note result: slice => string("def") + +;; CHECK: [fuzz-exec] calling slice-big +;; CHECK-NEXT: [fuzz-exec] note result: slice-big => string("defgh") ;; CHECK-NEXT: [fuzz-exec] comparing compare.1 ;; CHECK-NEXT: [fuzz-exec] comparing compare.10 ;; CHECK-NEXT: [fuzz-exec] comparing compare.2 @@ -344,3 +358,4 @@ ;; CHECK-NEXT: [fuzz-exec] comparing get_length ;; CHECK-NEXT: [fuzz-exec] comparing new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] comparing slice +;; CHECK-NEXT: [fuzz-exec] comparing slice-big |