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