fix(ecmascript): avoid charAt panic on 32-bit (#26244)

## Summary

- Return `OutOfRange` when a `StringCharAt` position cannot fit in `usize`, avoiding a panic on 32-bit targets.
- Cover the `u32` boundary in direct evaluation and minifier constant folding, alongside existing conversion and UTF-16 edge cases.
This commit is contained in:
camc314 committed 2026-09-02 09:07:00 +00:00
1 parent 34feccb479
commit 853ffabf34
2 files changed
+16 -1

No files matched your search

+14 -1
View File
@@ -14,7 +14,12 @@ impl StringCharAt for &str {
let position = pos.unwrap_or(0.0).to_integer_or_infinity_as_i64();
let position = match position {
ToIntegerOrInfinityResult::Value(v) if v >= 0 => v.to_usize().unwrap(),
ToIntegerOrInfinityResult::Value(v)
if v >= 0
&& let Some(v) = v.to_usize() =>
{
v
}
_ => return StringCharAtResult::OutOfRange,
};
@@ -47,10 +52,18 @@ mod test {
assert_eq!(s.char_at(Some(4.0)), StringCharAtResult::OutOfRange);
assert_eq!(s.char_at(Some(0.5)), StringCharAtResult::Value('t'));
assert_eq!(s.char_at(None), StringCharAtResult::Value('t'));
assert_eq!(s.char_at(Some(f64::NAN)), StringCharAtResult::Value('t'));
assert_eq!(s.char_at(Some(f64::INFINITY)), StringCharAtResult::OutOfRange);
assert_eq!(s.char_at(Some(f64::NEG_INFINITY)), StringCharAtResult::OutOfRange);
assert_eq!(s.char_at(Some(-1.0)), StringCharAtResult::OutOfRange);
assert_eq!(s.char_at(Some(-1.1)), StringCharAtResult::OutOfRange);
assert_eq!(s.char_at(Some(-1_073_741_825.0)), StringCharAtResult::OutOfRange);
assert_eq!(s.char_at(Some(f64::from(u32::MAX))), StringCharAtResult::OutOfRange);
assert_eq!(s.char_at(Some(f64::from(u32::MAX) + 1.0)), StringCharAtResult::OutOfRange);
let astral = "𝄞";
assert_eq!(astral.char_at(Some(0.0)), StringCharAtResult::InvalidChar(0xd834));
assert_eq!(astral.char_at(Some(1.0)), StringCharAtResult::InvalidChar(0xdd1e));
assert_eq!(astral.char_at(Some(2.0)), StringCharAtResult::OutOfRange);
}
}
@@ -242,6 +242,8 @@ fn test_fold_string_char_at() {
test("x = 'abcde'.charAt(3)", "x = 'd'");
test("x = 'abcde'.charAt(4)", "x = 'e'");
test("x = 'abcde'.charAt(5)", "x = ''");
test("x = 'abcde'.charAt(4294967295)", "x = ''");
test("x = 'abcde'.charAt(4294967296)", "x = ''");
test("x = 'abcde'.charAt(-1)", "x = ''");
test("x = 'abcde'.charAt()", "x = 'a'");
test_same("x = 'abcde'.charAt(...foo)");