mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-02 22:41:47 -06:00
Reject impossible dates such as Feb 30 in FormCalc Date2Num and Parse (#2388)
Found while testing crates/js/src/formcalc.rs:1916 Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
c97ca226e6
commit
0d864e2e31
@@ -1913,7 +1913,17 @@ fn parse_date(text: &str, picture: &str) -> Option<(i64, u32, u32)> {
|
||||
}
|
||||
}
|
||||
let (y, m, d) = (y?, m.unwrap_or(1), d.unwrap_or(1));
|
||||
((-200_000..=200_000).contains(&y) && (1..=12).contains(&m) && (1..=31).contains(&d)).then_some((y, m, d))
|
||||
((-200_000..=200_000).contains(&y) && (1..=12).contains(&m) && (1..=days_in(y, m)).contains(&d)).then_some((y, m, d))
|
||||
}
|
||||
|
||||
/// Number of days in month `m` (1-12) of year `y`, leap years included.
|
||||
fn days_in(y: i64, m: u32) -> u32 {
|
||||
match m {
|
||||
2 if (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 => 29,
|
||||
2 => 28,
|
||||
4 | 6 | 9 | 11 => 30,
|
||||
_ => 31,
|
||||
}
|
||||
}
|
||||
|
||||
fn format_date(y: i64, m: u32, d: u32, picture: &str) -> String {
|
||||
|
||||
@@ -692,6 +692,20 @@ mod formcalc {
|
||||
assert!(go("Nope(1)", "form1[0].page1[0].total[0]", "calculate").error.unwrap().contains("unknown function"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn date2num_rejects_days_past_the_end_of_the_month() {
|
||||
assert_eq!(calc(r#"Date2Num("2023-02-30")"#), "0");
|
||||
assert_eq!(calc(r#"Date2Num("31/04/2024", "DD/MM/YYYY")"#), "0");
|
||||
assert_eq!(calc(r#"Date2Num("2023-02-29")"#), "0");
|
||||
assert_eq!(calc(r#"Date2Num("1900-02-29")"#), "0");
|
||||
assert_eq!(calc(r#"Parse("YYYY-MM-DD", "2023-02-30") == null"#), "1");
|
||||
// Valid month ends still work.
|
||||
assert_eq!(calc(r#"Date2Num("2024-02-29")"#), "45350");
|
||||
assert_eq!(calc(r#"Date2Num("2000-02-29") <> 0"#), "1");
|
||||
assert_eq!(calc(r#"Date2Num("2024-04-30") <> 0"#), "1");
|
||||
assert_eq!(calc(r#"Date2Num("2024-12-31") <> 0"#), "1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn control_flow_variables_and_functions_work() {
|
||||
assert_eq!(calc("var x = 3\nif (x > 2) then 10 elseif (x > 1) then 20 else 30 endif"), "10");
|
||||
|
||||
Reference in New Issue
Block a user