Coverage Report

Created: 2025-07-11 06:21

/rust/registry/src/index.crates.io-6f17d22bba15001f/unsafe-libyaml-0.2.11/src/ops.rs
Line
Count
Source (jump to first uncovered line)
1
pub(crate) trait ForceAdd: Sized {
2
    fn force_add(self, rhs: Self) -> Self;
3
}
4
5
impl ForceAdd for u8 {
6
0
    fn force_add(self, rhs: Self) -> Self {
7
0
        self.checked_add(rhs).unwrap_or_else(die)
8
0
    }
9
}
10
11
impl ForceAdd for i32 {
12
538
    fn force_add(self, rhs: Self) -> Self {
13
538
        self.checked_add(rhs).unwrap_or_else(die)
14
538
    }
15
}
16
17
impl ForceAdd for u32 {
18
195k
    fn force_add(self, rhs: Self) -> Self {
19
195k
        self.checked_add(rhs).unwrap_or_else(die)
20
195k
    }
21
}
22
23
impl ForceAdd for u64 {
24
252M
    fn force_add(self, rhs: Self) -> Self {
25
252M
        self.checked_add(rhs).unwrap_or_else(die)
26
252M
    }
27
}
28
29
impl ForceAdd for usize {
30
702k
    fn force_add(self, rhs: Self) -> Self {
31
702k
        self.checked_add(rhs).unwrap_or_else(die)
32
702k
    }
33
}
34
35
pub(crate) trait ForceMul: Sized {
36
    fn force_mul(self, rhs: Self) -> Self;
37
}
38
39
impl ForceMul for i32 {
40
538
    fn force_mul(self, rhs: Self) -> Self {
41
538
        self.checked_mul(rhs).unwrap_or_else(die)
42
538
    }
43
}
44
45
impl ForceMul for i64 {
46
60.7k
    fn force_mul(self, rhs: Self) -> Self {
47
60.7k
        self.checked_mul(rhs).unwrap_or_else(die)
48
60.7k
    }
49
}
50
51
impl ForceMul for u64 {
52
0
    fn force_mul(self, rhs: Self) -> Self {
53
0
        self.checked_mul(rhs).unwrap_or_else(die)
54
0
    }
55
}
56
57
pub(crate) trait ForceInto {
58
    fn force_into<U>(self) -> U
59
    where
60
        Self: TryInto<U>;
61
}
62
63
impl<T> ForceInto for T {
64
702k
    fn force_into<U>(self) -> U
65
702k
    where
66
702k
        Self: TryInto<U>,
67
702k
    {
68
702k
        <Self as TryInto<U>>::try_into(self)
69
702k
            .ok()
70
702k
            .unwrap_or_else(die)
71
702k
    }
72
}
73
74
// Deterministically abort on arithmetic overflow, instead of wrapping and
75
// continuing with invalid behavior.
76
//
77
// This is impossible or nearly impossible to hit as the arithmetic computations
78
// in libyaml are all related to either:
79
//
80
//  - small integer processing (ascii, hex digits)
81
//  - allocation sizing
82
//
83
// and the only allocations in libyaml are for fixed-sized objects and
84
// geometrically growing buffers with a growth factor of 2. So in order for an
85
// allocation computation to overflow usize, the previous allocation for that
86
// container must have been filled to a size of usize::MAX/2, which is an
87
// allocation that would have failed in the allocator. But we check for this to
88
// be pedantic and to find out if it ever does happen.
89
//
90
// No-std abort is implemented using a double panic. On most platforms the
91
// current mechanism for this is for core::intrinsics::abort to invoke an
92
// invalid instruction. On Unix, the process will probably terminate with a
93
// signal like SIGABRT, SIGILL, SIGTRAP, SIGSEGV or SIGBUS. The precise
94
// behaviour is not guaranteed and not stable, but is safe.
95
#[cold]
96
0
pub(crate) fn die<T>() -> T {
97
    struct PanicAgain;
98
99
    impl Drop for PanicAgain {
100
0
        fn drop(&mut self) {
101
0
            panic!("arithmetic overflow");
102
        }
103
    }
104
105
0
    fn do_die() -> ! {
106
0
        let _panic_again = PanicAgain;
107
0
        panic!("arithmetic overflow");
108
    }
109
110
0
    do_die();
Unexecuted instantiation: unsafe_libyaml::ops::die::<core::alloc::layout::Layout>
Unexecuted instantiation: unsafe_libyaml::ops::die::<u8>
Unexecuted instantiation: unsafe_libyaml::ops::die::<usize>
Unexecuted instantiation: unsafe_libyaml::ops::die::<i32>
Unexecuted instantiation: unsafe_libyaml::ops::die::<u32>
Unexecuted instantiation: unsafe_libyaml::ops::die::<i64>
Unexecuted instantiation: unsafe_libyaml::ops::die::<u64>
111
}