This commit is contained in:
Dylan M. Taylor committed 2026-11-11 12:35:58 +00:00
1 parent 2a910bac02
commit 62e0b6f028
3 files changed
+5 -34

No files matched your search

+1 -2
View File
@@ -1,6 +1,5 @@
use super::host::{
FieldKey, arg, charge, colour, error, function, host, kind_of, read, s, set_value, strings, text, text_bytes, text_line, value_for, value_of,
write,
FieldKey, arg, charge, colour, error, function, host, kind_of, read, s, strings, text, text_bytes, text_line, value_for, value_of, write,
};
use super::model::{DISPLAY_HIDDEN, DISPLAY_VISIBLE, FieldType, Request};
use super::{Attribute, Context, JsArray, JsObject, JsResult, JsString, JsValue, NativeFunction, ObjectInitializer, js_string};
+4 -18
View File
@@ -150,24 +150,6 @@ pub(crate) fn function(ctx: &mut Context, f: NativeFunction) -> JsFunction {
FunctionObjectBuilder::new(ctx.realm(), f).build()
}
/// Bytes `s` takes once escaped by [`JsString::to_std_string_escaped`]: a valid scalar its UTF-8
/// length, an unpaired surrogate the six bytes of its `\uXXXX` escape. Counted without a copy,
/// and stopped once the count passes `cap`.
pub(crate) fn escaped_len(s: &JsString, cap: usize) -> usize {
use boa_engine::string::CodePoint;
let mut n = 0usize;
for cp in s.code_points() {
n = n.saturating_add(match cp {
CodePoint::Unicode(c) => c.len_utf8(),
CodePoint::UnpairedSurrogate(_) => 6,
});
if n > cap {
break;
}
}
n
}
/// Format exactly the escaped UTF-8 representation used by `text`, refusing a
/// write before it exceeds the remaining aggregate budget. No full Rust copy of
/// an oversized JavaScript string is made just to discover its byte length.
@@ -318,6 +300,10 @@ pub(crate) fn value_for(kind: FieldType, vals: Vec<String>) -> Vec<String> {
}
}
pub(crate) fn set_value(f: &mut FieldState, vals: Vec<String>) {
f.value = value_for(f.kind, vals);
}
#[cfg(test)]
mod string_budget_review_tests {
use super::*;
-14
View File
@@ -370,20 +370,6 @@ fn reset_form_and_field_setters_take_arrays_up_to_the_limit() {
assert_array_error("getField('total').value = new Array((1 << 20) + 1)");
}
/// The array byte check measures the escaped width, not six bytes per UTF-16 unit: ASCII text is
/// charged its own length, so an entry that fits is not refused.
#[test]
fn escaped_array_text_is_measured_by_its_width() {
use crate::host::escaped_len;
assert_eq!(escaped_len(&JsString::from("abc"), usize::MAX), 3);
assert_eq!(escaped_len(&JsString::from("é"), usize::MAX), 2);
assert_eq!(escaped_len(&JsString::from("界"), usize::MAX), 3);
let text = "a".repeat(6 << 20);
assert_eq!(escaped_len(&JsString::from(text.as_str()), usize::MAX), 6 << 20);
assert_eq!(escaped_len(&JsString::from(&[0xd800u16][..]), usize::MAX), 6, "an unpaired surrogate escapes to six bytes");
assert!(escaped_len(&JsString::from(text.as_str()), 10) < 6 << 20, "counting stops past the cap");
}
#[test]
fn reset_form_and_field_setters_still_read_short_arrays() {
let mut f = fields();