diff --git a/src/common/if_match.rs b/src/common/if_match.rs index bc2a8479..267bd760 100644 --- a/src/common/if_match.rs +++ b/src/common/if_match.rs @@ -108,4 +108,38 @@ mod tests { assert!(if_match.precondition_passes(&foo)); } + + #[test] + fn decode_empty() { + use crate::Header; + + assert!(IfMatch::decode(&mut [].iter()).is_err()); + assert!(IfMatch::decode(&mut [HeaderValue::from_static("")].iter()).is_err()); + assert!(IfMatch::decode(&mut [HeaderValue::from_static(" ")].iter()).is_err()); + } + + #[test] + fn decode_invalid() { + use crate::Header; + + assert!(IfMatch::decode(&mut [HeaderValue::from_static("no-quotes")].iter()).is_err()); + assert!(IfMatch::decode(&mut [HeaderValue::from_static("\"foo\", bad")].iter()).is_err()); + } + + #[test] + fn decode_valid() { + use crate::Header; + + let any = IfMatch::decode(&mut [HeaderValue::from_static("*")].iter()).unwrap(); + assert!(any.is_any()); + + let any_spaced = IfMatch::decode(&mut [HeaderValue::from_static(" * ")].iter()).unwrap(); + assert!(any_spaced.is_any()); + + let tags = + IfMatch::decode(&mut [HeaderValue::from_static("\"foo\", \"bar\"")].iter()).unwrap(); + assert!(tags.precondition_passes(&ETag::from_static("\"foo\""))); + assert!(tags.precondition_passes(&ETag::from_static("\"bar\""))); + assert!(!tags.precondition_passes(&ETag::from_static("\"baz\""))); + } } diff --git a/src/common/if_none_match.rs b/src/common/if_none_match.rs index 89a80dc0..d259faee 100644 --- a/src/common/if_none_match.rs +++ b/src/common/if_none_match.rs @@ -108,4 +108,41 @@ mod tests { assert!(!if_none.precondition_passes(&foo)); } + + #[test] + fn decode_empty() { + use crate::Header; + + assert!(IfNoneMatch::decode(&mut [].iter()).is_err()); + assert!(IfNoneMatch::decode(&mut [HeaderValue::from_static("")].iter()).is_err()); + assert!(IfNoneMatch::decode(&mut [HeaderValue::from_static(" ")].iter()).is_err()); + } + + #[test] + fn decode_invalid() { + use crate::Header; + + assert!(IfNoneMatch::decode(&mut [HeaderValue::from_static("no-quotes")].iter()).is_err()); + assert!( + IfNoneMatch::decode(&mut [HeaderValue::from_static("\"foo\", bad")].iter()).is_err() + ); + } + + #[test] + fn decode_valid() { + use crate::Header; + + let any = IfNoneMatch::decode(&mut [HeaderValue::from_static("*")].iter()).unwrap(); + assert!(!any.precondition_passes(&ETag::from_static("\"foo\""))); + + let any_spaced = + IfNoneMatch::decode(&mut [HeaderValue::from_static(" * ")].iter()).unwrap(); + assert!(!any_spaced.precondition_passes(&ETag::from_static("\"foo\""))); + + let tags = IfNoneMatch::decode(&mut [HeaderValue::from_static("\"foo\", \"bar\"")].iter()) + .unwrap(); + assert!(!tags.precondition_passes(&ETag::from_static("\"foo\""))); + assert!(!tags.precondition_passes(&ETag::from_static("\"bar\""))); + assert!(tags.precondition_passes(&ETag::from_static("\"baz\""))); + } } diff --git a/src/util/entity.rs b/src/util/entity.rs index 554bffb2..ff2942bd 100644 --- a/src/util/entity.rs +++ b/src/util/entity.rs @@ -252,10 +252,29 @@ impl super::TryFromValues for EntityTagRange { where I: Iterator, { - let flat = FlatCsv::try_from_values(values)?; - if flat.value == "*" { + let mut values = values.peekable(); + if values.peek().is_none() { + return Err(Error::invalid()); + } + let flat = FlatCsv::try_from_values(&mut values)?; + if flat + .value + .to_str() + .map(|s| s.trim() == "*") + .unwrap_or(false) + { Ok(EntityTagRange::Any) } else { + let mut count = 0; + for s in flat.iter() { + if EntityTag::<&str>::parse(s).is_none() { + return Err(Error::invalid()); + } + count += 1; + } + if count == 0 { + return Err(Error::invalid()); + } Ok(EntityTagRange::Tags(flat)) } }