Skip to content

Commit 0ab16e3

Browse files
dxbjavidJens-G
authored andcommitted
enforce max_string_size on non-strict binary message name
1 parent 817e0f1 commit 0ab16e3

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

lib/rs/src/protocol/binary.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,17 @@ where
137137
// is the message name. strings (byte arrays) are length-prefixed,
138138
// so we've just read the length in the first 4 bytes
139139
let name_size = BigEndian::read_i32(&first_bytes) as usize;
140+
if let Some(max_size) = self.config.max_string_size() {
141+
if name_size > max_size {
142+
return Err(crate::Error::Protocol(ProtocolError::new(
143+
ProtocolErrorKind::SizeLimit,
144+
format!(
145+
"Message name size {} exceeds maximum allowed size of {}",
146+
name_size, max_size
147+
),
148+
)));
149+
}
150+
}
140151
let mut name_buf: Vec<u8> = vec![0; name_size];
141152
self.transport.read_exact(&mut name_buf)?;
142153
let name = String::from_utf8(name_buf)?;
@@ -1265,6 +1276,56 @@ mod tests {
12651276
}
12661277
}
12671278

1279+
#[test]
1280+
fn must_enforce_string_size_limit_on_non_strict_message_name() {
1281+
let mem = TBufferChannel::with_capacity(100, 100);
1282+
let (r_mem, mut w_mem) = mem.split().unwrap();
1283+
1284+
let config = TConfiguration::builder()
1285+
.max_string_size(Some(1000))
1286+
.build()
1287+
.unwrap();
1288+
// non-strict: the first 4 bytes are the (positive) message-name length
1289+
let mut i_prot = TBinaryInputProtocol::with_config(r_mem, false, config);
1290+
1291+
w_mem.set_readable_bytes(&[0x00, 0x00, 0x07, 0xD0]);
1292+
1293+
let result = i_prot.read_message_begin();
1294+
assert!(result.is_err());
1295+
match result {
1296+
Err(crate::Error::Protocol(e)) => {
1297+
assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
1298+
assert!(e
1299+
.message
1300+
.contains("Message name size 2000 exceeds maximum allowed size of 1000"));
1301+
}
1302+
_ => panic!("Expected protocol error with SizeLimit"),
1303+
}
1304+
}
1305+
1306+
#[test]
1307+
fn must_allow_non_strict_message_name_at_limit() {
1308+
let mem = TBufferChannel::with_capacity(100, 100);
1309+
let (r_mem, mut w_mem) = mem.split().unwrap();
1310+
1311+
let config = TConfiguration::builder()
1312+
.max_string_size(Some(5))
1313+
.build()
1314+
.unwrap();
1315+
// non-strict: the first 4 bytes are the (positive) message-name length
1316+
let mut i_prot = TBinaryInputProtocol::with_config(r_mem, false, config);
1317+
1318+
// name length 5 (== limit), name "hello", message type Call, sequence 0
1319+
w_mem.set_readable_bytes(&[
1320+
0x00, 0x00, 0x00, 0x05, b'h', b'e', b'l', b'l', b'o', 0x01, 0x00, 0x00, 0x00, 0x00,
1321+
]);
1322+
1323+
let ident = i_prot.read_message_begin().unwrap();
1324+
assert_eq!(ident.name, "hello");
1325+
assert_eq!(ident.message_type, TMessageType::Call);
1326+
assert_eq!(ident.sequence_number, 0);
1327+
}
1328+
12681329
#[test]
12691330
fn must_allow_strings_within_limit() {
12701331
let mem = TBufferChannel::with_capacity(100, 100);

0 commit comments

Comments
 (0)