summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsis Lovecruft <isis@torproject.org>2018-03-27 21:38:29 +0000
committerIsis Lovecruft <isis@torproject.org>2018-04-02 19:59:15 +0000
commit4b4e36a413bb5d0e2ea499dd6bc34b3d24bd3375 (patch)
treeac3c224e9f4a7d2326e36cbfc55ba36ca3f2afab
parent6739a69c590a12af0f1cb2af62972f4305803670 (diff)
downloadtor-4b4e36a413bb5d0e2ea499dd6bc34b3d24bd3375.tar.xz
tor-4b4e36a413bb5d0e2ea499dd6bc34b3d24bd3375.zip
rust: Port all C protover_all_supported tests to Rust.
The behaviours still do not match, unsurprisingly, but now we know where a primary difference is: the Rust is validating version ranges more than the C, so in the C it's possible to call protover_all_supported on a ridiculous version range like "Sleen=0-4294967294" because the C uses MAX_PROTOCOLS_TO_EXPAND to count the number of *subprotocols* whereas the Rust uses it to count the total number of *versions* of all subprotocols.
-rw-r--r--src/rust/protover/tests/protover.rs86
1 files changed, 83 insertions, 3 deletions
diff --git a/src/rust/protover/tests/protover.rs b/src/rust/protover/tests/protover.rs
index 9f8b5a443..11015f35b 100644
--- a/src/rust/protover/tests/protover.rs
+++ b/src/rust/protover/tests/protover.rs
@@ -6,6 +6,7 @@ extern crate protover;
use protover::ProtoEntry;
use protover::ProtoverVote;
use protover::UnvalidatedProtoEntry;
+use protover::errors::ProtoverError;
#[test]
fn parse_protocol_with_single_proto_and_single_version() {
@@ -320,9 +321,88 @@ fn protover_compute_vote_may_exceed_limit() {
}
#[test]
-fn protover_all_supported_should_include_version_we_actually_do_support() {
+fn protover_all_supported_should_exclude_versions_we_actually_do_support() {
let proto: UnvalidatedProtoEntry = "Link=3-999".parse().unwrap();
- let _result: String = proto.all_supported().unwrap().to_string();
+ let result: String = proto.all_supported().unwrap().to_string();
- assert_eq!(_result, "Link=3-999".to_string());
+ assert_eq!(result, "Link=6-999".to_string());
+}
+
+#[test]
+fn protover_all_supported_should_exclude_versions_we_actually_do_support_complex1() {
+ let proto: UnvalidatedProtoEntry = "Link=1-3,345-666".parse().unwrap();
+ let result: String = proto.all_supported().unwrap().to_string();
+
+ assert_eq!(result, "Link=345-666".to_string());
+}
+
+#[test]
+fn protover_all_supported_should_exclude_versions_we_actually_do_support_complex2() {
+ let proto: UnvalidatedProtoEntry = "Link=1-3,5-12".parse().unwrap();
+ let result: String = proto.all_supported().unwrap().to_string();
+
+ assert_eq!(result, "Link=6-12".to_string());
+}
+
+#[test]
+fn protover_all_supported_should_exclude_some_versions_and_entire_protocols() {
+ let proto: UnvalidatedProtoEntry = "Link=1-3,5-12 Quokka=9000-9001".parse().unwrap();
+ let result: String = proto.all_supported().unwrap().to_string();
+
+ assert_eq!(result, "Link=6-12 Quokka=9000-9001".to_string());
+}
+
+#[test]
+#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: ExceedsMax")]
+// C_RUST_DIFFERS: This test fails in Rust (but not in C) because an
+// UnvalidatedProtoEntry is defined as a Hashmap<UnknownProtocol, ProtoSet>.
+// Because it contains the ProtoSet part, there's still *some* validation
+// happening, so in this case the DoS protections in the Rust code are kicking
+// in because the range here is exceeds the maximum, so it returns an
+// Err(ProtoverError::ExceedsMax). The C, however seems to parse it anyway.
+fn protover_all_supported_should_not_dos_anyones_computer() {
+ let proto: UnvalidatedProtoEntry = "Sleen=0-2147483648".parse().unwrap();
+ let result: String = proto.all_supported().unwrap().to_string();
+
+ assert_eq!(result, "Sleen=0-2147483648".to_string());
+}
+
+#[test]
+#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: ExceedsMax")]
+// C_RUST_DIFFERS: This test fails in Rust (but not in C) because an
+// UnvalidatedProtoEntry is defined as a Hashmap<UnknownProtocol, ProtoSet>.
+// Because it contains the ProtoSet part, there's still *some* validation
+// happening, so in this case the DoS protections in the Rust code are kicking
+// in because the range here is exceeds the maximum, so it returns an
+// Err(ProtoverError::ExceedsMax). The C, however seems to parse it anyway.
+fn protover_all_supported_should_not_dos_anyones_computer_max_versions() {
+ let proto: UnvalidatedProtoEntry = "Sleen=0-4294967294".parse().unwrap();
+ let result: String = proto.all_supported().unwrap().to_string();
+
+ assert_eq!(result, "Sleen=0-4294967294".to_string());
+}
+
+#[test]
+// C_RUST_DIFFERS: The C will return true (e.g. saying "yes, that's supported")
+// but set the msg to NULL (??? seems maybe potentially bad). The Rust will
+// simply return a None.
+fn protover_all_supported_should_return_empty_string_for_weird_thing() {
+ let proto: UnvalidatedProtoEntry = "Fribble=".parse().unwrap();
+ let result: Option<UnvalidatedProtoEntry> = proto.all_supported();
+
+ assert!(result.is_none());
+}
+
+#[test]
+fn protover_unvalidatedprotoentry_should_err_entirely_unparseable_things() {
+ let proto: Result<UnvalidatedProtoEntry, ProtoverError> = "Fribble".parse();
+
+ assert_eq!(Err(ProtoverError::Unparseable), proto);
+}
+
+#[test]
+fn protover_all_supported_over_maximum_limit() {
+ let proto: Result<UnvalidatedProtoEntry, ProtoverError> = "Sleen=0-4294967295".parse();
+
+ assert_eq!(Err(ProtoverError::ExceedsMax), proto);
}