Skip to content

Commit 07ebe59

Browse files
authored
fix(engine): use code_unit_at instead of code_point_at in URI Decode (#5168)
This Pull Request fixes/closes #5166. It changes the following: - Fixes URI Decode to read UTF-16 code units at index k instead of reading a code point and truncating to u16. - Corrects `decodeURI` and `decodeURIComponent` behavior for non-BMP characters such as `\uD83D\uDE00`, matching ECMAScript Decode step 4.b and Node/Chrome behavior. - Adds regression tests to keep non-BMP decode behavior correct. Testing: - `cargo test -p boa_engine uri` - `cargo fmt --all` Spec reference: https://tc39.es/ecma262/#sec-decode
1 parent e2ab577 commit 07ebe59

File tree

1 file changed

+17
-5
lines changed
  • core/engine/src/builtins/uri

1 file changed

+17
-5
lines changed

core/engine/src/builtins/uri/mod.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,10 @@ where
379379
// 4. Repeat,
380380
loop {
381381
// a. If k = strLen, return R.
382-
if k == str_len {
383-
return Ok(js_string!(&r[..]));
384-
}
385-
386382
// b. Let C be the code unit at index k within string.
387-
let c = string.code_point_at(k).as_u32() as u16;
383+
let Some(c) = string.code_unit_at(k) else {
384+
return Ok(js_string!(&r[..]));
385+
};
388386

389387
// c. If C is not the code unit 0x0025 (PERCENT SIGN), then
390388
#[allow(clippy::if_not_else)]
@@ -589,4 +587,18 @@ mod tests {
589587
let native = err.as_native().expect("error should be native");
590588
assert!(matches!(native.kind(), JsNativeErrorKind::Uri));
591589
}
590+
591+
#[test]
592+
fn decode_preserves_non_bmp_characters() {
593+
let s = js_string!("\u{1F600}");
594+
let decoded = decode(&s, |_| false).expect("decode should succeed");
595+
assert_eq!(decoded, s);
596+
}
597+
598+
#[test]
599+
fn decode_preserves_non_bmp_characters_for_decode_uri_set() {
600+
let s = js_string!("\u{1F600}");
601+
let decoded = decode(&s, is_uri_reserved_or_number_sign).expect("decode should succeed");
602+
assert_eq!(decoded, s);
603+
}
592604
}

0 commit comments

Comments
 (0)