Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that FixedInt and FixedUInt handle zero-length integers #762

Merged
merged 2 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src/lazy/encoder/binary/v1_1/fixed_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ impl FixedInt {
}

let value: Int = if input.len() <= 8 {
// Look at the last byte in the input that is part of the FixedInt; this is the most significant byte.
let most_significant_byte = input[size_in_bytes - 1];
let sign_bit = most_significant_byte & 0b1000_0000;
// Create a buffer that is filled with the sign bit that we can write into.
// Any bytes not overwritten will be an extension of the sign bit.
let mut buffer = if sign_bit == 0 { [0x0; 8] } else { [0xFF; 8] };
buffer[..size_in_bytes].copy_from_slice(input);
i64::from_le_bytes(buffer).into()
let mut buffer = [0x0; 8];
// Copy the input into the buffer as the _most_ significant bits, read as i64, and then
// shift right to the correct position, extending the sign.
buffer[(8 - size_in_bytes)..8].copy_from_slice(input);
i64::from_le_bytes(buffer)
.checked_shr(64 - (size_in_bytes as u32 * 8))
.unwrap_or(0)
.into()
} else {
BigInt::from_signed_bytes_le(&input[..size_in_bytes]).into()
};
Expand Down Expand Up @@ -255,6 +255,18 @@ mod tests {
Ok(())
}

#[test]
fn decode_zero_length_fixed_int() -> IonResult<()> {
let encoding = &[];
let fixed_int = FixedInt::read(encoding, encoding.len(), 0)?;
let actual_value = fixed_int.value().expect_i64()?;
assert_eq!(
actual_value, 0,
"actual value {actual_value} was != expected value 0 for encoding {encoding:x?}"
);
Ok(())
}

#[test]
fn encode_fixed_int() -> IonResult<()> {
// Make two copies of each of our tests. In the first, each i64 is turned into a Int.
Expand Down
12 changes: 12 additions & 0 deletions src/lazy/encoder/binary/v1_1/fixed_uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ mod tests {
Ok(())
}

#[test]
fn decode_zero_length_fixed_uint() -> IonResult<()> {
let encoding = &[];
let fixed_uint = FixedUInt::read(encoding, encoding.len(), 0)?;
let actual_value = fixed_uint.value().expect_u64()?;
assert_eq!(
actual_value, 0,
"actual value {actual_value} was != expected value 0 for encoding {encoding:x?}"
);
Ok(())
}

#[test]
fn encode_fixed_uint() -> IonResult<()> {
// Make two copies of each of our tests. In the first, each u64 is turned into a UInt.
Expand Down
Loading