fix: validate Temporal duration inputs

This commit is contained in:
爱特每羊队
2026-08-11 13:11:51 +08:00
parent d7a63a0d54
commit 925ca358e9
3 changed files with 201 additions and 39 deletions
@@ -338,6 +338,8 @@ pub fn bind_temporal(core: &Arc<KernelCore>, session: &KernelSession, global: &m
&[
("abs", oxide_builtins::temporal::duration_abs::<crate::vm::Vm> as *const (), 0),
("negated", oxide_builtins::temporal::duration_negated::<crate::vm::Vm> as *const (), 0),
("with", oxide_builtins::temporal::duration_with::<crate::vm::Vm> as *const (), 1),
("total", oxide_builtins::temporal::duration_total::<crate::vm::Vm> as *const (), 1),
("toString", oxide_builtins::temporal::duration_to_string::<crate::vm::Vm> as *const (), 0),
("valueOf", oxide_builtins::temporal::duration_value_of::<crate::vm::Vm> as *const (), 0),
],
@@ -234,6 +234,44 @@ fn duration_constructor_exposes_components() {
assert_eq!(str_val(&vm, r), "P1Y2M3W4D");
}
#[test]
fn duration_from_validates_property_bags_and_preserves_precision() {
let mut vm = Vm::new();
let r = eval(&mut vm, "try { Temporal.Duration.from({}) } catch (e) { e.constructor.name }").unwrap();
assert_eq!(str_val(&vm, r), "TypeError");
let r = eval(
&mut vm,
"try { Temporal.Duration.from({hours:1,minutes:-1}) } catch (e) { e.constructor.name }",
)
.unwrap();
assert_eq!(str_val(&vm, r), "RangeError");
let r = eval(
&mut vm,
"Temporal.Duration.from({milliseconds:4503599627370497000,microseconds:4503599627370495000000}).toString()",
)
.unwrap();
assert_eq!(str_val(&vm, r), "PT9007199254740991.975424S");
}
#[test]
fn duration_from_propagates_getter_errors_and_checks_range() {
let mut vm = Vm::new();
let r = eval(
&mut vm,
"try { Temporal.Duration.from({get years(){throw new TypeError('sentinel')}}) } catch (e) { e.message }",
)
.unwrap();
assert_eq!(str_val(&vm, r), "sentinel");
let r = eval(
&mut vm,
"try { Temporal.Duration.from({seconds:9007199254740992}) } catch (e) { e.constructor.name }",
)
.unwrap();
assert_eq!(str_val(&vm, r), "RangeError");
let r = eval(&mut vm, "Temporal.Duration.from('p1y1m1dt1h1m1s').toString()").unwrap();
assert_eq!(str_val(&vm, r), "P1Y1M1DT1H1M1S");
}
#[test]
fn plain_date_balances_duration_time_units_into_days() {
let mut vm = Vm::new();