@@ -113,12 +113,13 @@ impl ContextIDComponentInner {
113113 match ( generated_context_id, creation_timestamp_s) {
114114 // We generated a new context ID then we need a fresh timestamp and no rotation needed
115115 ( true , _) => ( now, true , false ) ,
116- // Pre-existing context ID with valid timestamp then use timestamp and no rotation needed
117- ( false , secs) if secs > 0 => (
118- DateTime :: < Utc > :: from_timestamp ( secs, 0 ) . unwrap_or ( now) ,
119- false ,
120- false ,
121- ) ,
116+ // Pre-existing context ID with a positive timestamp:
117+ // try parsing it (any real UNIX-epoch timestamp is orders of magnitude within chrono’s 262 000-year range),
118+ // and if it’s somehow out-of-range fall back to `now` and force rotation
119+ // See: https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDateTime.html#panics
120+ ( false , secs) if secs > 0 => DateTime :: < Utc > :: from_timestamp ( secs, 0 )
121+ . map ( |ts| ( ts, false , false ) )
122+ . unwrap_or ( ( now, true , true ) ) ,
122123 // Pre-existing context ID with zero timestamp then use current time and no rotation needed
123124 ( false , 0 ) => ( now, true , false ) ,
124125 // Pre-existing context ID but INVALID timestamp then use current time but FORCE rotation
@@ -453,6 +454,44 @@ mod tests {
453454 } ) ;
454455 }
455456
457+ #[ test]
458+ fn test_context_id_with_out_of_range_creation_date ( ) {
459+ with_test_mars ( |mars, delete_called| {
460+ let spy = SpyCallback :: new ( ) ;
461+ // Way beyond chrono’s 262.000 syear range
462+ let huge_secs = i64:: MAX ;
463+ let component = ContextIDComponentInner :: new (
464+ TEST_CONTEXT_ID ,
465+ huge_secs,
466+ false ,
467+ spy. callback ,
468+ * FAKE_NOW ,
469+ mars,
470+ ) ;
471+
472+ // A new UUID should have been generated.
473+ assert ! ( Uuid :: parse_str( & component. context_id) . is_ok( ) ) ;
474+ assert_ne ! ( component. context_id, TEST_CONTEXT_ID ) ;
475+
476+ // The creation timestamp must have been set to now.
477+ assert_eq ! ( component. creation_timestamp, FAKE_NOW . clone( ) ) ;
478+
479+ // Also expect a persist to have been called and a rotation.
480+ assert_eq ! (
481+ * spy. persist_called. lock( ) . unwrap( ) ,
482+ 1 ,
483+ "persist() should have been called once"
484+ ) ;
485+ assert_eq ! (
486+ * spy. rotated_called. lock( ) . unwrap( ) ,
487+ 1 ,
488+ "rotated() should have been called once"
489+ ) ;
490+ // Since we forced a rotation on out-of-range, the MARS delete should have been called.
491+ assert ! ( * delete_called. lock( ) . unwrap( ) ) ;
492+ } ) ;
493+ }
494+
456495 #[ test]
457496 fn test_request_no_rotation ( ) {
458497 with_test_mars ( |mars, delete_called| {
0 commit comments