1#[derive(Debug, Clone)]
7pub struct BoundsConfig {
8 pub check_array_access: bool,
9 pub check_integer_overflow: bool,
10 pub check_division_by_zero: bool,
11}
12
13impl Default for BoundsConfig {
14 fn default() -> Self {
15 Self {
16 check_array_access: true,
17 check_integer_overflow: true,
18 check_division_by_zero: true,
19 }
20 }
21}
22
23#[derive(Debug, Clone, Copy)]
25pub enum OverflowCheck {
26 Safe,
27 MayOverflow,
28 WillOverflow,
29}
30
31pub struct BoundsChecker {
33 config: BoundsConfig,
34}
35
36impl BoundsChecker {
37 pub fn new(config: BoundsConfig) -> Self {
38 Self { config }
39 }
40
41 pub fn check_add_overflow(&self, a: i128, b: i128, bits: u32) -> OverflowCheck {
42 if !self.config.check_integer_overflow {
43 return OverflowCheck::Safe;
44 }
45 let max = (1i128 << (bits - 1)) - 1;
46 let min = -(1i128 << (bits - 1));
47 match a.checked_add(b) {
48 Some(r) if r >= min && r <= max => OverflowCheck::Safe,
49 Some(_) => OverflowCheck::WillOverflow,
50 None => OverflowCheck::WillOverflow,
51 }
52 }
53}
54
55impl Default for BoundsChecker {
56 fn default() -> Self {
57 Self::new(BoundsConfig::default())
58 }
59}