修复(会员账期): 北京时间年份越界先收口再进历法换算
- beijing_local_micros 增加 ±292_278 年范围检查,避免 days_from_civil 内部 i32 乘法溢出 - 补充 10_000_000 年等溢出用例
This commit is contained in:
@@ -25,7 +25,10 @@ pub fn beijing_local_date_parts(micros: i64) -> (i32, u8, u8, i64) {
|
||||
/// 返回 `Option` 而不是用 `0` 兼作非法哨兵:北京 1970-01-01 08:00 本身就是合法的 `0`,
|
||||
/// 调用方必须能区分「非法日期」与「合法 epoch」。
|
||||
pub fn beijing_local_micros(year: i32, month: u8, day: u8, time_of_day_micros: i64) -> Option<i64> {
|
||||
if !(1..=12).contains(&month)
|
||||
// 中文注释:先按 i64 微秒可表示范围(约 ±292_278 年)收口年份,避免 `days_from_civil`
|
||||
// 内部的 `era * 146_097` 在 i32 上溢出(debug panic / release 回绕成看似合法的值)。
|
||||
if !(-292_278..=292_278).contains(&year)
|
||||
|| !(1..=12).contains(&month)
|
||||
|| day == 0
|
||||
|| day > days_in_month(year, month)
|
||||
|| !(0..PROFILE_RUNTIME_DAY_MICROS).contains(&time_of_day_micros)
|
||||
@@ -155,6 +158,9 @@ mod tests {
|
||||
// 中文注释:超出 i64 微秒范围的年份必须返回 None,而不是饱和成看似合法的值。
|
||||
assert_eq!(beijing_local_micros(1_000_000, 1, 1, 0), None);
|
||||
assert_eq!(beijing_local_micros(-1_000_000, 1, 1, 0), None);
|
||||
// 这些年份会让 days_from_civil 内部的 i32 乘法溢出,必须在进入历法换算前收口。
|
||||
assert_eq!(beijing_local_micros(10_000_000, 1, 1, 0), None);
|
||||
assert_eq!(beijing_local_micros(-10_000_000, 1, 1, 0), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user