@@ -78,18 +78,24 @@ pub(crate) fn parse_path<'a>(path: &'a str) -> Result<Vec<(PathKey<'a>, bool)>>
7878 }
7979 let mut num: Option < Integer > = None ;
8080 while let Some ( & ( _, c @ '0' ..='9' ) ) = chars. peek ( ) {
81+ let digit = ( c as u8 - b'0' ) as Integer ;
8182 let new_num = num
8283 . unwrap_or ( 0 )
8384 . checked_mul ( 10 )
84- . and_then ( |n| n. checked_add ( ( c as u8 - b'0' ) as Integer ) )
85+ . and_then ( |n| {
86+ if negative {
87+ n. checked_sub ( digit)
88+ } else {
89+ n. checked_add ( digit)
90+ }
91+ } )
8592 . ok_or_else ( || {
8693 Error :: runtime ( format ! ( "integer overflow in path at position {pos}" ) )
8794 } ) ?;
8895 num = Some ( new_num) ;
8996 chars. next ( ) ; // consume digit
9097 }
9198 match num {
92- Some ( n) if negative => PathKey :: Int ( -n) ,
9399 Some ( n) => PathKey :: Int ( n) ,
94100 None => {
95101 let err = format ! ( "invalid integer in path at position {pos}" ) ;
@@ -209,6 +215,10 @@ mod tests {
209215 assert ! ( matches!( path[ 3 ] , ( PathKey :: Str ( ref s) , false ) if s == "c" ) ) ;
210216 assert ! ( matches!( path[ 4 ] , ( PathKey :: Str ( ref s) , false ) if s == "d" ) ) ;
211217
218+ let min_path = format ! ( "a[{}]" , crate :: Integer :: MIN ) ;
219+ let path = parse_path ( & min_path) . unwrap ( ) ;
220+ assert ! ( matches!( path[ 1 ] , ( PathKey :: Int ( n) , false ) if n == crate :: Integer :: MIN ) ) ;
221+
212222 // Test empty path
213223 let path = parse_path ( "" ) . unwrap ( ) ;
214224 assert_eq ! ( path. len( ) , 0 ) ;
@@ -249,6 +259,9 @@ mod tests {
249259 // Test bad integers
250260 let err = parse_path ( "a[99999999999999999999]" ) . unwrap_err ( ) . to_string ( ) ;
251261 assert_eq ! ( err, "runtime error: integer overflow in path at position 2" ) ;
262+ let negative_overflow = format ! ( "a[{}0]" , crate :: Integer :: MIN ) ;
263+ let err = parse_path ( & negative_overflow) . unwrap_err ( ) . to_string ( ) ;
264+ assert_eq ! ( err, "runtime error: integer overflow in path at position 2" ) ;
252265 let err = parse_path ( "a[-]" ) . unwrap_err ( ) . to_string ( ) ;
253266 assert_eq ! ( err, "runtime error: invalid integer in path at position 2" ) ;
254267 }
0 commit comments