@@ -145,7 +145,12 @@ fn format_with_modifiers(
145145 // Check if this specifier has modifiers
146146 if !flags. is_empty ( ) || !width_str. is_empty ( ) {
147147 // Apply modifiers to the formatted value
148- let width: usize = width_str. parse ( ) . unwrap_or ( 0 ) ;
148+ // Cap width to i32::MAX to match GNU behavior, which uses int for width.
149+ // Without this cap, very large widths (e.g., %8888888888r) cause issues.
150+ let width: usize = width_str
151+ . parse :: < usize > ( )
152+ . unwrap_or ( 0 )
153+ . min ( i32:: MAX as usize ) ;
149154 let explicit_width = !width_str. is_empty ( ) ;
150155 let modified = apply_modifiers ( & formatted, flags, width, spec, explicit_width) ;
151156 result. push_str ( & modified) ;
@@ -710,4 +715,23 @@ mod tests {
710715 "GNU: %_C should produce '19', not ' 19' (default width is 2, not 4)"
711716 ) ;
712717 }
718+
719+ #[ test]
720+ fn test_large_width_capped ( ) {
721+ // Regression test: very large widths caused OOM.
722+ // We cap width to i32::MAX to match GNU behavior.
723+ // Test with a reasonable width to avoid allocating 2GB in tests.
724+ let value = "12:00:00 AM" ;
725+ let result = apply_modifiers ( value, "" , 100 , "r" , true ) ;
726+ assert_eq ! ( result. len( ) , 100 ) ;
727+
728+ // Verify that the width capping logic works
729+ // The parse and min operations should handle this correctly
730+ let width_str = "8888888888" ;
731+ let width = width_str
732+ . parse :: < usize > ( )
733+ . unwrap_or ( 0 )
734+ . min ( i32:: MAX as usize ) ;
735+ assert_eq ! ( width, i32 :: MAX as usize ) ;
736+ }
713737}
0 commit comments