Merge remote-tracking branch 'onionk/rust-protocommas1' into maint-0.3.5

This commit is contained in:
Nick Mathewson 2018-10-19 14:20:57 -04:00
commit 1ae9116601
2 changed files with 19 additions and 17 deletions

3
changes/bug27197 Normal file
View File

@ -0,0 +1,3 @@
o Minor bugfixes (protover, rust):
- Reject extra commas in version string. Fixes bug 27197; bugfix on
0.3.3.3-alpha.

View File

@ -352,23 +352,25 @@ impl FromStr for ProtoSet {
/// assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("3-")); /// assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("3-"));
/// assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1-,4")); /// assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1-,4"));
/// ///
/// // Things which would get parsed into an _empty_ `ProtoSet` are, /// // An empty string is, however, legal, and results in an
/// // however, legal, and result in an empty `ProtoSet`: /// // empty `ProtoSet`:
/// assert_eq!(Ok(ProtoSet::default()), ProtoSet::from_str("")); /// assert_eq!(Ok(ProtoSet::default()), ProtoSet::from_str(""));
/// assert_eq!(Ok(ProtoSet::default()), ProtoSet::from_str(",,,"));
/// # /// #
/// # Ok(protoset) /// # Ok(protoset)
/// # } /// # }
/// # fn main() { do_test(); } // wrap the test so we can use the ? operator /// # fn main() { do_test(); } // wrap the test so we can use the ? operator
/// ``` /// ```
fn from_str(version_string: &str) -> Result<Self, Self::Err> { fn from_str(version_string: &str) -> Result<Self, Self::Err> {
// If we were passed in an empty string, then return an empty ProtoSet.
if version_string.is_empty() {
return Ok(Self::default());
}
let mut pairs: Vec<(Version, Version)> = Vec::new(); let mut pairs: Vec<(Version, Version)> = Vec::new();
let pieces: ::std::str::Split<char> = version_string.split(','); let pieces: ::std::str::Split<char> = version_string.split(',');
for p in pieces { for p in pieces {
if p.is_empty() { if p.contains('-') {
continue;
} else if p.contains('-') {
let mut pair = p.splitn(2, '-'); let mut pair = p.splitn(2, '-');
let low = pair.next().ok_or(ProtoverError::Unparseable)?; let low = pair.next().ok_or(ProtoverError::Unparseable)?;
@ -377,24 +379,14 @@ impl FromStr for ProtoSet {
let lo: Version = low.parse().or(Err(ProtoverError::Unparseable))?; let lo: Version = low.parse().or(Err(ProtoverError::Unparseable))?;
let hi: Version = high.parse().or(Err(ProtoverError::Unparseable))?; let hi: Version = high.parse().or(Err(ProtoverError::Unparseable))?;
if lo == u32::MAX || hi == u32::MAX {
return Err(ProtoverError::ExceedsMax);
}
pairs.push((lo, hi)); pairs.push((lo, hi));
} else { } else {
let v: u32 = p.parse().or(Err(ProtoverError::Unparseable))?; let v: u32 = p.parse().or(Err(ProtoverError::Unparseable))?;
if v == u32::MAX {
return Err(ProtoverError::ExceedsMax);
}
pairs.push((v, v)); pairs.push((v, v));
} }
} }
// If we were passed in an empty string, or
// simply a comma, or a pile of commas, then return an empty ProtoSet.
if pairs.len() == 0 {
return Ok(ProtoSet::default());
}
ProtoSet::from_slice(&pairs[..]) ProtoSet::from_slice(&pairs[..])
} }
} }
@ -558,6 +550,13 @@ mod test {
assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("-1")); assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("-1"));
} }
#[test]
fn test_versions_from_str_commas() {
assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str(","));
assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1,,2"));
assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1,2,"));
}
#[test] #[test]
fn test_versions_from_str_hyphens() { fn test_versions_from_str_hyphens() {
assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("--1")); assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("--1"));