@@ -34,14 +34,14 @@ impl FixedInt {
34
34
}
35
35
36
36
let value: Int = if input. len ( ) <= 8 {
37
- // Look at the last byte in the input that is part of the FixedInt; this is the most significant byte.
38
- let most_significant_byte = input[ size_in_bytes - 1 ] ;
39
- let sign_bit = most_significant_byte & 0b1000_0000 ;
40
- // Create a buffer that is filled with the sign bit that we can write into.
41
- // Any bytes not overwritten will be an extension of the sign bit.
42
- let mut buffer = if sign_bit == 0 { [ 0x0 ; 8 ] } else { [ 0xFF ; 8 ] } ;
43
- buffer [ ..size_in_bytes ] . copy_from_slice ( input ) ;
44
- i64 :: from_le_bytes ( buffer ) . into ( )
37
+ let mut buffer = [ 0x0 ; 8 ] ;
38
+ // Copy the input into the buffer as the _most_ significant bits, read as i64, and then
39
+ // shift right to the correct position, extending the sign.
40
+ buffer[ ( 8 - size_in_bytes ) .. 8 ] . copy_from_slice ( input ) ;
41
+ i64 :: from_le_bytes ( buffer )
42
+ . checked_shr ( 64 - ( size_in_bytes as u32 * 8 ) )
43
+ . unwrap_or ( 0 )
44
+ . into ( )
45
45
} else {
46
46
BigInt :: from_signed_bytes_le ( & input[ ..size_in_bytes] ) . into ( )
47
47
} ;
@@ -255,6 +255,18 @@ mod tests {
255
255
Ok ( ( ) )
256
256
}
257
257
258
+ #[ test]
259
+ fn decode_zero_length_fixed_int ( ) -> IonResult < ( ) > {
260
+ let encoding = & [ ] ;
261
+ let fixed_int = FixedInt :: read ( encoding, encoding. len ( ) , 0 ) ?;
262
+ let actual_value = fixed_int. value ( ) . expect_i64 ( ) ?;
263
+ assert_eq ! (
264
+ actual_value, 0 ,
265
+ "actual value {actual_value} was != expected value 0 for encoding {encoding:x?}"
266
+ ) ;
267
+ Ok ( ( ) )
268
+ }
269
+
258
270
#[ test]
259
271
fn encode_fixed_int ( ) -> IonResult < ( ) > {
260
272
// Make two copies of each of our tests. In the first, each i64 is turned into a Int.
0 commit comments