Skip to content

Commit

Permalink
Fix bug where is_canonical() would erroneously return true
Browse files Browse the repository at this point in the history
on messages with certain pathological intersegment pointers.

The bug was reported by Mathias Svensson of Seasoned Software.
  • Loading branch information
dwrensha committed Mar 9, 2018
1 parent 112992a commit e72746c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
4 changes: 4 additions & 0 deletions capnp/src/private/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,10 @@ impl <'a> PointerReader<'a> {
}

pub fn is_canonical(&self, read_head: &Cell<*const Word>) -> Result<bool> {
if self.pointer.is_null() || unsafe { !(*self.pointer).is_positional() } {
return Ok(false)
}

match try!(self.get_pointer_type()) {
PointerType::Null => Ok(true),
PointerType::Struct => {
Expand Down
19 changes: 19 additions & 0 deletions capnp/tests/canonicalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,3 +512,22 @@ fn out_of_bounds_zero_sized_void_list_returns_error() {
let message = message::Reader::new(segment_array, Default::default());
assert!(message.is_canonical().is_err());
}

#[test]
fn far_pointer_to_same_segment() {
let segment: &[Word] = &[
// Far pointer to this same segment. Landing pad is two words, offset of one.
capnp_word!(0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),

// Landing pad. Again, points back to this same segment.
capnp_word!(0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),

// Tag word, describing struct with 2-word data section.
capnp_word!(0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00),
];

let segments = &[segment];
let segment_array = message::SegmentArray::new(segments);
let message = message::Reader::new(segment_array, Default::default());
assert!(!message.is_canonical().unwrap());
}

0 comments on commit e72746c

Please sign in to comment.