Skip to content

Commit 4de55c1

Browse files
authored
Prevent precompute of stringview_wtf16.slice splitting unicode codepoints. (#7320)
1 parent f346257 commit 4de55c1

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/wasm-interpreter.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,6 +2273,20 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
22732273

22742274
Literals contents;
22752275
if (endVal > startVal) {
2276+
// Check that the slice is valid; since we can assume that we have a valid
2277+
// UTF-16, we only need to check that it did not split surrgate pairs.
2278+
auto firstChar = refValues[startVal].getInteger();
2279+
if (firstChar >= 0xDC00 && firstChar <= 0xDFFF) {
2280+
// The first char cannot be a low surrogate.
2281+
return Flow(NONCONSTANT_FLOW);
2282+
}
2283+
2284+
auto lastChar = refValues[endVal - 1].getInteger();
2285+
if (lastChar >= 0xD800 && lastChar <= 0xDBFF) {
2286+
// The last char cannot be a high surrogate.
2287+
return Flow(NONCONSTANT_FLOW);
2288+
}
2289+
22762290
contents.reserve(endVal - startVal);
22772291
for (size_t i = startVal; i < endVal; i++) {
22782292
if (i < refValues.size()) {

test/lit/passes/precompute-strings.wast

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
;; CHECK: (export "slice-unicode" (func $slice-unicode))
2828

29+
;; CHECK: (export "slice-invalid-unicode-end" (func $slice-invalid-unicode-end))
30+
31+
;; CHECK: (export "slice-invalid-unicode-begin" (func $slice-invalid-unicode-begin))
32+
2933
;; CHECK: (func $eq-no (type $0) (result i32)
3034
;; CHECK-NEXT: (i32.const 0)
3135
;; CHECK-NEXT: )
@@ -225,6 +229,39 @@
225229
)
226230
)
227231

232+
;; CHECK: (func $slice-invalid-unicode-end (type $2) (result (ref string))
233+
;; CHECK-NEXT: (stringview_wtf16.slice
234+
;; CHECK-NEXT: (string.const "a\f0\90\8d\86b")
235+
;; CHECK-NEXT: (i32.const 0)
236+
;; CHECK-NEXT: (i32.const 2)
237+
;; CHECK-NEXT: )
238+
;; CHECK-NEXT: )
239+
(func $slice-invalid-unicode-end (export "slice-invalid-unicode-end") (result (ref string))
240+
(stringview_wtf16.slice
241+
;; a𐍆b
242+
(string.const "a\f0\90\8d\86b")
243+
(i32.const 0)
244+
(i32.const 2)
245+
)
246+
)
247+
248+
;; CHECK: (func $slice-invalid-unicode-begin (type $2) (result (ref string))
249+
;; CHECK-NEXT: (stringview_wtf16.slice
250+
;; CHECK-NEXT: (string.const "a\f0\90\8d\86b")
251+
;; CHECK-NEXT: (i32.const 2)
252+
;; CHECK-NEXT: (i32.const 4)
253+
;; CHECK-NEXT: )
254+
;; CHECK-NEXT: )
255+
(func $slice-invalid-unicode-begin (export "slice-invalid-unicode-begin") (result (ref string))
256+
(stringview_wtf16.slice
257+
;; a𐍆b
258+
(string.const "a\f0\90\8d\86b")
259+
(i32.const 2)
260+
(i32.const 4)
261+
)
262+
)
263+
264+
228265
;; CHECK: (func $string.new-mutable (type $3) (result anyref)
229266
;; CHECK-NEXT: (string.new_wtf16_array
230267
;; CHECK-NEXT: (array.new_fixed $array16 4

0 commit comments

Comments
 (0)