Skip to content

Commit a029e50

Browse files
committed
Validate offsets do not point beyond end of message
1 parent 1b21bbc commit a029e50

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/error.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ pub enum Error {
3131
/// Request was less than 1024 bytes
3232
RequestTooShort,
3333

34-
/// Offset within message was not 32-bit aligned
34+
/// Offset was not 32-bit aligned
3535
InvalidOffsetAlignment(u32),
3636

37+
/// Offset is outside of valid message range
38+
InvalidOffsetValue(u32),
39+
3740
/// Invalid number of tags specified
3841
InvalidNumTags(u32),
3942

src/message.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,17 @@ impl RtMessage {
6767

6868
let mut offsets = Vec::with_capacity((num_tags - 1) as usize);
6969
let mut tags = Vec::with_capacity(num_tags as usize);
70+
let end_of_data = bytes.len() as u32;
7071

7172
for _ in 0..num_tags - 1 {
7273
let offset = msg.read_u32::<LittleEndian>()?;
74+
7375
if offset % 4 != 0 {
7476
return Err(Error::InvalidOffsetAlignment(offset));
77+
} else if offset > end_of_data {
78+
return Err(Error::InvalidOffsetValue(offset));
7579
}
80+
7681
offsets.push(offset as usize);
7782
}
7883

@@ -343,4 +348,32 @@ mod test {
343348
// Everything was read
344349
assert_eq!(encoded.position() as usize, msg.encoded_size());
345350
}
351+
352+
#[test]
353+
#[should_panic(expected="InvalidOffsetValue(128)")]
354+
fn from_bytes_offset_past_end_of_message() {
355+
let mut msg = RtMessage::new(2);
356+
msg.add_field(Tag::NONC, "1111".as_bytes()).unwrap();
357+
msg.add_field(Tag::PAD, "aaaaaaaaa".as_bytes()).unwrap();
358+
359+
let mut bytes = msg.encode().unwrap();
360+
// set the PAD value offset to beyond end of the message
361+
bytes[4] = 128;
362+
363+
RtMessage::from_bytes(&bytes).unwrap();
364+
}
365+
366+
#[test]
367+
#[should_panic(expected="InvalidNumTags(0)")]
368+
fn from_bytes_zero_tags() {
369+
let mut msg = RtMessage::new(1);
370+
msg.add_field(Tag::NONC, "1111".as_bytes()).unwrap();
371+
372+
let mut bytes = msg.encode().unwrap();
373+
// set num_tags to zero
374+
bytes[0] = 0;
375+
376+
RtMessage::from_bytes(&bytes).unwrap();
377+
}
378+
346379
}

0 commit comments

Comments
 (0)