From f1cf9064105bedcfce861aa4c564d6d5749b09e6 Mon Sep 17 00:00:00 2001 From: Covertness <wuyingfengsui@gmail.com> Date: Thu, 20 Aug 2015 22:07:32 +0800 Subject: [PATCH] add test case --- Cargo.toml | 5 ++++- src/client.rs | 22 ++++++++++++++++++++++ src/lib.rs | 1 + src/packet.rs | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 56ab3c4..af42945 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,7 @@ mio = "0.3.7" threadpool = "0.1" url = "0.2.36" num = "0.1" -rand = "0.3" \ No newline at end of file +rand = "0.3" + +[dev-dependencies] +quickcheck = "*" \ No newline at end of file diff --git a/src/client.rs b/src/client.rs index d92077c..13ec0fb 100644 --- a/src/client.rs +++ b/src/client.rs @@ -138,4 +138,26 @@ impl CoAPClient { _ => SchemeType::NonRelative, } } +} + + +#[cfg(test)] +mod test { + use super::*; + use packet::{Packet, PacketType}; + + #[test] + fn test_request_error_url() { + assert!(CoAPClient::request("http://127.0.0.1").is_err()); + assert!(CoAPClient::request("coap://127.0.0.").is_err()); + assert!(CoAPClient::request("127.0.0.1").is_err()); + } + + #[test] + fn test_reply_error() { + let client = CoAPClient::new("127.0.0.1:5683").unwrap(); + let mut packet = Packet::new(); + packet.header.set_type(PacketType::Acknowledgement); + assert!(client.reply(&packet, b"Test".to_vec()).is_err()); + } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 664ace2..2eaa9c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,7 @@ extern crate threadpool; extern crate url; extern crate num; extern crate rand; +#[cfg(test)] extern crate quickcheck; pub use server::CoAPServer; pub use client::CoAPClient; diff --git a/src/packet.rs b/src/packet.rs index 691e95f..878c1a1 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -229,9 +229,16 @@ impl Packet { 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 { @@ -239,9 +246,17 @@ impl Packet { } 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 { @@ -251,6 +266,9 @@ impl Packet { 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) { @@ -474,4 +492,19 @@ mod test { packet.payload = "Hello".as_bytes().to_vec(); assert_eq!(packet.to_bytes().unwrap(), vec!(0x64, 0x45, 0x13, 0xFD, 0xD0, 0xE2, 0x4D, 0xAC, 0xFF, 0x48, 0x65, 0x6C, 0x6C, 0x6F)); } + + #[test] + fn test_malicious_packet() { + use quickcheck::{QuickCheck, TestResult}; + + fn run(x: Vec<u8>) -> TestResult { + match Packet::from_bytes(&x[..]) { + Ok(packet) => { + TestResult::from_bool(packet.get_token().len() == packet.header.get_token_length() as usize) + }, + Err(_) => TestResult::passed() + } + } + QuickCheck::new().tests(10000).quickcheck(run as fn(Vec<u8>) -> TestResult) + } } \ No newline at end of file -- GitLab