From c973618e9b6782d41bc3a63e8d96c52fa19dd224 Mon Sep 17 00:00:00 2001 From: James Munns <james.munns@gmail.com> Date: Thu, 2 Jun 2016 02:10:09 +0200 Subject: [PATCH] Options should be parsed even if there is no token --- src/packet.rs | 135 +++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 68 deletions(-) diff --git a/src/packet.rs b/src/packet.rs index 51d1923..c2a8b09 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -199,95 +199,94 @@ impl Packet { match header_result { Ok(header) => { let token_length = header.get_token_length(); - let (mut token, mut payload) = (Vec::new(), Vec::new()); - let mut options: BTreeMap<usize, LinkedList<Vec<u8>>> = BTreeMap::new(); + let options_start: usize = 4 + token_length as usize; - if token_length > 0 { - if token_length > 8 { - return Err(ParseError::InvalidTokenLength); - } + if token_length > 8 { + return Err(ParseError::InvalidTokenLength); + } - let options_start: usize = 4 + token_length as usize; - if options_start > buf.len() { - return Err(ParseError::InvalidTokenLength); - } + if options_start > buf.len() { + return Err(ParseError::InvalidTokenLength); + } - token = buf[4..options_start].to_vec(); + let token = buf[4..options_start].to_vec(); - let mut idx = options_start; - let mut options_number = 0; - while idx < buf.len() { - let byte = buf[idx]; + let mut idx = options_start; + let mut options_number = 0; + let mut options: BTreeMap<usize, LinkedList<Vec<u8>>> = BTreeMap::new(); + while idx < buf.len() { + let byte = buf[idx]; - if byte == 255 || idx > buf.len() { - break; - } + if byte == 255 || idx > buf.len() { + break; + } - let mut delta = (byte >> 4) as usize; - let mut length = (byte & 0xF) as usize; + let mut delta = (byte >> 4) as usize; + let mut length = (byte & 0xF) as usize; - idx += 1; + idx += 1; - if delta == 13 { - if idx >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - delta = buf[idx] as usize + 13; - idx += 1; - } else if delta == 14 { - if idx + 1 >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - - delta = (u16::from_be(u8_to_unsigned_be!(buf, idx, idx + 1, u16)) + 269) as usize; - idx += 2; - } else if delta == 15 { - return Err(ParseError::InvalidOptionDelta); + if delta == 13 { + if idx >= buf.len() { + return Err(ParseError::InvalidOptionLength); } - - if length == 13 { - if idx >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - - length = buf[idx] as usize + 13; - idx += 1; - } else if length == 14 { - if idx + 1 >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - - length = (u16::from_be(u8_to_unsigned_be!(buf, idx, idx + 1, u16)) + 269) as usize; - idx += 2; - } else if length == 15 { + delta = buf[idx] as usize + 13; + idx += 1; + } else if delta == 14 { + if idx + 1 >= buf.len() { return Err(ParseError::InvalidOptionLength); } - options_number += delta; + delta = (u16::from_be(u8_to_unsigned_be!(buf, idx, idx + 1, u16)) + 269) as usize; + idx += 2; + } else if delta == 15 { + return Err(ParseError::InvalidOptionDelta); + } - let end = idx + length; - if end > buf.len() { + if length == 13 { + if idx >= buf.len() { return Err(ParseError::InvalidOptionLength); } - let options_value = buf[idx..end].to_vec(); - - if options.contains_key(&options_number) { - let mut options_list = options.get_mut(&options_number).unwrap(); - options_list.push_back(options_value); - } else { - let mut list = LinkedList::new(); - list.push_back(options_value); - options.insert(options_number, list); + + length = buf[idx] as usize + 13; + idx += 1; + } else if length == 14 { + if idx + 1 >= buf.len() { + return Err(ParseError::InvalidOptionLength); } - idx += length; + length = (u16::from_be(u8_to_unsigned_be!(buf, idx, idx + 1, u16)) + 269) as usize; + idx += 2; + } else if length == 15 { + return Err(ParseError::InvalidOptionLength); } - if idx < buf.len() { - payload = buf[(idx + 1)..buf.len()].to_vec(); + options_number += delta; + + let end = idx + length; + if end > buf.len() { + return Err(ParseError::InvalidOptionLength); + } + let options_value = buf[idx..end].to_vec(); + + if options.contains_key(&options_number) { + let mut options_list = options.get_mut(&options_number).unwrap(); + options_list.push_back(options_value); + } else { + let mut list = LinkedList::new(); + list.push_back(options_value); + options.insert(options_number, list); } + + idx += length; + } + + let mut payload = Vec::new(); + if idx < buf.len() { + payload = buf[(idx + 1)..buf.len()].to_vec(); } + Ok(Packet { header: header, token: token, @@ -508,4 +507,4 @@ mod test { } QuickCheck::new().tests(10000).gen(StdGen::new(rand::thread_rng(), 1500)).quickcheck(run as fn(Vec<u8>) -> TestResult) } -} \ No newline at end of file +} -- GitLab