Skip to content

Commit

Permalink
Support previously and currently documented encodings for boolean lists
Browse files Browse the repository at this point in the history
  • Loading branch information
jhorstmann authored and Jens-G committed Feb 4, 2025
1 parent a630739 commit 717bd79
Showing 1 changed file with 45 additions and 1 deletion.
46 changes: 45 additions & 1 deletion lib/rs/src/protocol/compact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ where
None => {
let b = self.read_byte()?;
match b {
// Previous versions of the thrift compact protocol specification said to use 0
// and 1 inside collections, but that differed from existing implementations.
// The specification was updated in https://github.com/apache/thrift/commit/2c29c5665bc442e703480bb0ee60fe925ffe02e8.
0x00 => Ok(false),
0x01 => Ok(true),
0x02 => Ok(false),
unkn => Err(crate::Error::Protocol(crate::ProtocolError {
Expand Down Expand Up @@ -652,7 +656,11 @@ fn type_to_u8(field_type: TType) -> u8 {

fn collection_u8_to_type(b: u8) -> crate::Result<TType> {
match b {
0x01 => Ok(TType::Bool),
// For historical and compatibility reasons, a reader should be capable to deal with both cases.
// The only valid value in the original spec was 2, but due to a widespread implementation bug
// the defacto standard across large parts of the library became 1 instead.
// As a result, both values are now allowed.
0x01 | 0x02 => Ok(TType::Bool),
o => u8_to_type(o),
}
}
Expand Down Expand Up @@ -2839,4 +2847,40 @@ mod tests {
assert!(write_fn(&mut o_prot).is_ok());
assert_eq!(o_prot.transport.write_bytes().len(), 0);
}

#[test]
fn must_read_boolean_list() {
let (mut i_prot, _) = test_objects();

let source_bytes: [u8; 3] = [0x21, 2, 1];

i_prot.transport.set_readable_bytes(&source_bytes);

let (ttype, element_count) = assert_success!(i_prot.read_list_set_begin());

assert_eq!(ttype, TType::Bool);
assert_eq!(element_count, 2);
assert_eq!(i_prot.read_bool().unwrap(), false);
assert_eq!(i_prot.read_bool().unwrap(), true);

assert_success!(i_prot.read_list_end());
}

#[test]
fn must_read_boolean_list_alternative_encoding() {
let (mut i_prot, _) = test_objects();

let source_bytes: [u8; 3] = [0x22, 0, 1];

i_prot.transport.set_readable_bytes(&source_bytes);

let (ttype, element_count) = assert_success!(i_prot.read_list_set_begin());

assert_eq!(ttype, TType::Bool);
assert_eq!(element_count, 2);
assert_eq!(i_prot.read_bool().unwrap(), false);
assert_eq!(i_prot.read_bool().unwrap(), true);

assert_success!(i_prot.read_list_end());
}
}

0 comments on commit 717bd79

Please sign in to comment.