mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 22:58:50 +01:00
Merge branch 'maint-0.3.3' into maint-0.3.4
This commit is contained in:
commit
2ddbaf9cdc
4 changed files with 45 additions and 20 deletions
4
changes/bug27206
Normal file
4
changes/bug27206
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor bugfixes (rust):
|
||||||
|
- protover_all_supported() would attempt to allocate up to 16GB on some
|
||||||
|
inputs, leading to a potential memory DoS. Fixes bug 27206; bugfix on
|
||||||
|
0.3.3.5-rc.
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
//! Sets for lazily storing ordered, non-overlapping ranges of integers.
|
//! Sets for lazily storing ordered, non-overlapping ranges of integers.
|
||||||
|
|
||||||
|
use std::cmp;
|
||||||
|
use std::iter;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
@ -240,8 +242,8 @@ impl ProtoSet {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retain only the `Version`s in this `ProtoSet` for which the predicate
|
/// Returns all the `Version`s in `self` which are not also in the `other`
|
||||||
/// `F` returns `true`.
|
/// `ProtoSet`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -250,24 +252,45 @@ impl ProtoSet {
|
||||||
/// use protover::protoset::ProtoSet;
|
/// use protover::protoset::ProtoSet;
|
||||||
///
|
///
|
||||||
/// # fn do_test() -> Result<bool, ProtoverError> {
|
/// # fn do_test() -> Result<bool, ProtoverError> {
|
||||||
/// let mut protoset: ProtoSet = "1,3-5,9".parse()?;
|
/// let protoset: ProtoSet = "1,3-6,10-12,15-16".parse()?;
|
||||||
|
/// let other: ProtoSet = "2,5-7,9-11,14-20".parse()?;
|
||||||
///
|
///
|
||||||
/// // Keep only versions less than or equal to 8:
|
/// let subset: ProtoSet = protoset.and_not_in(&other);
|
||||||
/// protoset.retain(|x| x <= &8);
|
|
||||||
///
|
///
|
||||||
/// assert_eq!(protoset.expand(), vec![1, 3, 4, 5]);
|
/// assert_eq!(subset.expand(), vec![1, 3, 4, 12]);
|
||||||
/// #
|
/// #
|
||||||
/// # Ok(true)
|
/// # Ok(true)
|
||||||
/// # }
|
/// # }
|
||||||
/// # 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
|
||||||
/// ```
|
/// ```
|
||||||
// XXX we could probably do something more efficient here. —isis
|
pub fn and_not_in(&self, other: &Self) -> Self {
|
||||||
pub fn retain<F>(&mut self, f: F)
|
if self.is_empty() || other.is_empty() {
|
||||||
where F: FnMut(&Version) -> bool
|
return self.clone();
|
||||||
{
|
}
|
||||||
let mut expanded: Vec<Version> = self.clone().expand();
|
|
||||||
expanded.retain(f);
|
let pairs = self.iter().flat_map(|&(lo, hi)| {
|
||||||
*self = expanded.into();
|
let the_end = (hi + 1, hi + 1); // special case to mark the end of the range.
|
||||||
|
let excluded_ranges = other
|
||||||
|
.iter()
|
||||||
|
.cloned() // have to be owned tuples, to match iter::once(the_end).
|
||||||
|
.skip_while(move|&(_, hi2)| hi2 < lo) // skip the non-overlapping ranges.
|
||||||
|
.take_while(move|&(lo2, _)| lo2 <= hi) // take all the overlapping ones.
|
||||||
|
.chain(iter::once(the_end));
|
||||||
|
|
||||||
|
let mut nextlo = lo;
|
||||||
|
excluded_ranges.filter_map(move |(excluded_lo, excluded_hi)| {
|
||||||
|
let pair = if nextlo < excluded_lo {
|
||||||
|
Some((nextlo, excluded_lo - 1))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
nextlo = cmp::min(excluded_hi, u32::MAX - 1) + 1;
|
||||||
|
pair
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let pairs = pairs.collect();
|
||||||
|
ProtoSet::is_ok(ProtoSet{ pairs }).expect("should be already sorted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -354,7 +354,6 @@ impl UnvalidatedProtoEntry {
|
||||||
|
|
||||||
let maybe_supported_versions: Option<&ProtoSet> = supported.get(&supported_protocol);
|
let maybe_supported_versions: Option<&ProtoSet> = supported.get(&supported_protocol);
|
||||||
let supported_versions: &ProtoSet;
|
let supported_versions: &ProtoSet;
|
||||||
let mut unsupported_versions: ProtoSet;
|
|
||||||
|
|
||||||
// If the protocol wasn't in the map, then we don't know about it
|
// If the protocol wasn't in the map, then we don't know about it
|
||||||
// and don't support any of its versions. Add its versions to the
|
// and don't support any of its versions. Add its versions to the
|
||||||
|
@ -367,8 +366,7 @@ impl UnvalidatedProtoEntry {
|
||||||
} else {
|
} else {
|
||||||
supported_versions = maybe_supported_versions.unwrap();
|
supported_versions = maybe_supported_versions.unwrap();
|
||||||
}
|
}
|
||||||
unsupported_versions = versions.clone();
|
let unsupported_versions = versions.and_not_in(supported_versions);
|
||||||
unsupported_versions.retain(|x| !supported_versions.contains(x));
|
|
||||||
|
|
||||||
if !unsupported_versions.is_empty() {
|
if !unsupported_versions.is_empty() {
|
||||||
unsupported.insert(protocol.clone(), unsupported_versions);
|
unsupported.insert(protocol.clone(), unsupported_versions);
|
||||||
|
|
|
@ -354,18 +354,18 @@ fn protover_all_supported_should_exclude_some_versions_and_entire_protocols() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn protover_all_supported_should_not_dos_anyones_computer() {
|
fn protover_all_supported_should_not_dos_anyones_computer() {
|
||||||
let proto: UnvalidatedProtoEntry = "Sleen=1-2147483648".parse().unwrap();
|
let proto: UnvalidatedProtoEntry = "Link=1-2147483648".parse().unwrap();
|
||||||
let result: String = proto.all_supported().unwrap().to_string();
|
let result: String = proto.all_supported().unwrap().to_string();
|
||||||
|
|
||||||
assert_eq!(result, "Sleen=1-2147483648".to_string());
|
assert_eq!(result, "Link=6-2147483648".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn protover_all_supported_should_not_dos_anyones_computer_max_versions() {
|
fn protover_all_supported_should_not_dos_anyones_computer_max_versions() {
|
||||||
let proto: UnvalidatedProtoEntry = "Sleen=1-4294967294".parse().unwrap();
|
let proto: UnvalidatedProtoEntry = "Link=1-4294967294".parse().unwrap();
|
||||||
let result: String = proto.all_supported().unwrap().to_string();
|
let result: String = proto.all_supported().unwrap().to_string();
|
||||||
|
|
||||||
assert_eq!(result, "Sleen=1-4294967294".to_string());
|
assert_eq!(result, "Link=6-4294967294".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Reference in a new issue