Skip to content

Commit

Permalink
Range checks for types (#210)
Browse files Browse the repository at this point in the history
* draft status of ranges

* finished ranges. fixes for rust update, fixed test cases

* Fixing many edge cases for uint/nint/int ranges

now tests for both preserve-encodings and not with all 3 of those
as well as bounds that go across both
  • Loading branch information
rooooooooob authored Nov 14, 2023
1 parent 9661c92 commit 3385715
Show file tree
Hide file tree
Showing 10 changed files with 826 additions and 534 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ cbor_event = "2.4.0"
cddl = "0.9.1"
clap = { version = "4.3.12", features = ["derive"] }
codegen = { git = "https://github.com/dcSpark/codegen", branch = "master" }
either = "1.8.1"
once_cell = "1.18.0"
nom = "7.1.1"
pathdiff = "0.2.1"
Expand Down
372 changes: 264 additions & 108 deletions src/generation.rs

Large diffs are not rendered by default.

295 changes: 175 additions & 120 deletions src/intermediate.rs

Large diffs are not rendered by default.

518 changes: 215 additions & 303 deletions src/parsing.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion static/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub enum DeserializeFailure {
NoVariantMatched,
NoVariantMatchedWithCauses(Vec<DeserializeError>),
RangeCheck{
found: usize,
found: isize,
min: Option<isize>,
max: Option<isize>,
},
Expand Down
9 changes: 9 additions & 0 deletions tests/core/input.cddl
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,13 @@ array_opt_fields = [
y: 3.14159265
? e: non_overlapping_type_choice_some
? z: 2.71828
]

bounds = [
w: -1000 .. 1000
x: uint .le 7,
y: nint .ge -5,
z: text .size (3..14),
a: [* uint] .size (1..3),
b: { * uint => uint } .le 3
]
76 changes: 76 additions & 0 deletions tests/core/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,80 @@ mod tests {
}
}
}

#[test]
fn bounds() {
deser_test(&Bounds::new(10, 5, 3, "abc".to_owned(), vec![5], [(0, 1), (2, 3)].into()));
enum OOB {
Below,
Lower,
Upper,
Above,
}
let make_bounds = |w_out: OOB, x_out: OOB, y_out: OOB, z_out: OOB, a_out: OOB, b_out: OOB| {
let cbor = vec![
arr_def(6),
cbor_int(match w_out {
OOB::Below => -1001,
OOB::Lower => -1000,
OOB::Upper => 1000,
OOB::Above => 1001,
}, cbor_event::Sz::Two),
cbor_int(match x_out {
OOB::Below => panic!(),
OOB::Lower => panic!(),
OOB::Upper => 7,
OOB::Above => 8,
}, cbor_event::Sz::Inline),
cbor_int(match y_out {
OOB::Below => -6,
OOB::Lower => -5,
OOB::Upper => panic!(),
OOB::Above => panic!(),
}, cbor_event::Sz::Inline),
cbor_string(match z_out {
OOB::Below => "ab",
OOB::Lower => "abc",
OOB::Upper => "abcdefghijklmn",
OOB::Above => "abcdefghijklmno",
}),
vec![ARR_INDEF],
match a_out {
OOB::Below => vec![],
OOB::Lower => vec![0x00],
OOB::Upper => vec![0x00, 0x01, 0x02],
OOB::Above => vec![0x00, 0x01, 0x02, 0x03],
},
vec![BREAK],
vec![MAP_INDEF],
match b_out {
OOB::Below => panic!(),
OOB::Lower => panic!(),
OOB::Upper => vec![0x00, 0x00, 0x01, 0x01, 0x02, 0x02],
OOB::Above => vec![0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03],
},
vec![BREAK],
].into_iter().flatten().clone().collect::<Vec<u8>>();
Bounds::from_cbor_bytes(&cbor)
};
let good1 = make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Lower, OOB::Lower, OOB::Upper).unwrap();
deser_test(&good1);
let good2 = make_bounds(OOB::Upper, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).unwrap();
deser_test(&good2);
// w oob
assert!(make_bounds(OOB::Below, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
assert!(make_bounds(OOB::Above, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
// x oob
assert!(make_bounds(OOB::Lower, OOB::Above, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
// y oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Below, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
// z oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Below, OOB::Upper, OOB::Upper).is_err());
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Above, OOB::Upper, OOB::Upper).is_err());
// a oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Below, OOB::Upper).is_err());
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Above, OOB::Upper).is_err());
// b oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Above).is_err());
}
}
9 changes: 9 additions & 0 deletions tests/preserve-encodings/input.cddl
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,13 @@ array_opt_fields = [
y: #6.10(1),
? e: non_overlapping_type_choice_some
; ? z: null,
]

bounds = [
w: -1000 .. 1000
x: uint .le 7,
y: nint .ge -5,
z: text .size (3..14),
a: [* uint] .size (1..3),
b: { * uint => uint } .le 3
]
77 changes: 77 additions & 0 deletions tests/preserve-encodings/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,4 +715,81 @@ mod tests {
}
}
}

#[test]
fn bounds() {
// here we're just making sure that the code compiles + checks bounds with the preserve-encodings codegen
// all members here have their round-trip checked in other tests.
enum OOB {
Below,
Lower,
Upper,
Above,
}
let make_bounds = |w_out: OOB, x_out: OOB, y_out: OOB, z_out: OOB, a_out: OOB, b_out: OOB| {
let cbor = vec![
arr_def(6),
cbor_int(match w_out {
OOB::Below => -1001,
OOB::Lower => -1000,
OOB::Upper => 1000,
OOB::Above => 1001,
}, cbor_event::Sz::Two),
cbor_int(match x_out {
OOB::Below => panic!(),
OOB::Lower => panic!(),
OOB::Upper => 7,
OOB::Above => 8,
}, cbor_event::Sz::Inline),
cbor_int(match y_out {
OOB::Below => -6,
OOB::Lower => -5,
OOB::Upper => panic!(),
OOB::Above => panic!(),
}, cbor_event::Sz::Inline),
cbor_string(match z_out {
OOB::Below => "ab",
OOB::Lower => "abc",
OOB::Upper => "abcdefghijklmn",
OOB::Above => "abcdefghijklmno",
}),
vec![ARR_INDEF],
match a_out {
OOB::Below => vec![],
OOB::Lower => vec![0x00],
OOB::Upper => vec![0x00, 0x01, 0x02],
OOB::Above => vec![0x00, 0x01, 0x02, 0x03],
},
vec![BREAK],
vec![MAP_INDEF],
match b_out {
OOB::Below => panic!(),
OOB::Lower => panic!(),
OOB::Upper => vec![0x00, 0x00, 0x01, 0x01, 0x02, 0x02],
OOB::Above => vec![0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03],
},
vec![BREAK],
].into_iter().flatten().clone().collect::<Vec<u8>>();
Bounds::from_cbor_bytes(&cbor)
};
let good1 = make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Lower, OOB::Lower, OOB::Upper).unwrap();
deser_test(&good1);
let good2 = make_bounds(OOB::Upper, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).unwrap();
deser_test(&good2);
// w oob
assert!(make_bounds(OOB::Below, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
assert!(make_bounds(OOB::Above, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
// x oob
assert!(make_bounds(OOB::Lower, OOB::Above, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
// y oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Below, OOB::Upper, OOB::Upper, OOB::Upper).is_err());
// z oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Below, OOB::Upper, OOB::Upper).is_err());
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Above, OOB::Upper, OOB::Upper).is_err());
// a oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Below, OOB::Upper).is_err());
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Above, OOB::Upper).is_err());
// b oob
assert!(make_bounds(OOB::Lower, OOB::Upper, OOB::Lower, OOB::Upper, OOB::Upper, OOB::Above).is_err());
}
}

0 comments on commit 3385715

Please sign in to comment.