Coverage Report

Created: 2026-06-21 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasmparser/src/collections/hash.rs
Line
Count
Source
1
//! Utilities for hashmap initialization based on random sources.
2
3
use core::hash::{BuildHasher, Hasher};
4
5
/// Wasmparser's hashing state stored per-map.
6
///
7
/// This is DoS-resistant when the `std` feature is activated and still somewhat
8
/// resistant when it's not active but not as secure.
9
#[derive(Clone, Debug)]
10
pub struct RandomState(RandomStateImpl);
11
12
impl Default for RandomState {
13
    #[inline]
14
4.10M
    fn default() -> RandomState {
15
4.10M
        RandomState(RandomStateImpl::default())
16
4.10M
    }
17
}
18
19
impl BuildHasher for RandomState {
20
    type Hasher = RandomStateHasher;
21
22
    #[inline]
23
7.15M
    fn build_hasher(&self) -> RandomStateHasher {
24
7.15M
        RandomStateHasher(self.0.build_hasher())
25
7.15M
    }
26
}
27
28
/// Wasmparser's hasher type used with [`RandomState`].
29
pub struct RandomStateHasher(<RandomStateImpl as BuildHasher>::Hasher);
30
31
impl Hasher for RandomStateHasher {
32
    #[inline]
33
7.15M
    fn finish(&self) -> u64 {
34
7.15M
        self.0.finish()
35
7.15M
    }
36
    #[inline]
37
1.65M
    fn write(&mut self, bytes: &[u8]) {
38
1.65M
        self.0.write(bytes)
39
1.65M
    }
40
    #[inline]
41
4.10M
    fn write_u8(&mut self, i: u8) {
42
4.10M
        self.0.write_u8(i)
43
4.10M
    }
44
    #[inline]
45
0
    fn write_u16(&mut self, i: u16) {
46
0
        self.0.write_u16(i)
47
0
    }
48
    #[inline]
49
20.4M
    fn write_u32(&mut self, i: u32) {
50
20.4M
        self.0.write_u32(i)
51
20.4M
    }
52
    #[inline]
53
0
    fn write_u64(&mut self, i: u64) {
54
0
        self.0.write_u64(i)
55
0
    }
56
    #[inline]
57
0
    fn write_u128(&mut self, i: u128) {
58
0
        self.0.write_u128(i)
59
0
    }
60
    #[inline]
61
3.51M
    fn write_usize(&mut self, i: usize) {
62
3.51M
        self.0.write_usize(i)
63
3.51M
    }
64
    #[inline]
65
0
    fn write_i8(&mut self, i: i8) {
66
0
        self.0.write_i8(i)
67
0
    }
68
    #[inline]
69
0
    fn write_i16(&mut self, i: i16) {
70
0
        self.0.write_i16(i)
71
0
    }
72
    #[inline]
73
0
    fn write_i32(&mut self, i: i32) {
74
0
        self.0.write_i32(i)
75
0
    }
76
    #[inline]
77
0
    fn write_i64(&mut self, i: i64) {
78
0
        self.0.write_i64(i)
79
0
    }
80
    #[inline]
81
0
    fn write_i128(&mut self, i: i128) {
82
0
        self.0.write_i128(i)
83
0
    }
84
    #[inline]
85
7.07M
    fn write_isize(&mut self, i: isize) {
86
7.07M
        self.0.write_isize(i)
87
7.07M
    }
88
}
89
90
// When the `std` feature is active reuse the standard library's implementation
91
// of hash state and hasher.
92
#[cfg(feature = "std")]
93
use std::collections::hash_map::RandomState as RandomStateImpl;
94
95
// When the `std` feature is NOT active then rely on `ahash::RandomState`. That
96
// relies on ASLR by default for randomness.
97
#[derive(Clone, Debug)]
98
#[cfg(not(feature = "std"))]
99
struct RandomStateImpl {
100
    state: hashbrown::DefaultHashBuilder,
101
}
102
103
#[cfg(not(feature = "std"))]
104
impl Default for RandomStateImpl {
105
    fn default() -> RandomStateImpl {
106
        RandomStateImpl {
107
            state: hashbrown::DefaultHashBuilder::default(),
108
        }
109
    }
110
}
111
112
#[cfg(not(feature = "std"))]
113
impl BuildHasher for RandomStateImpl {
114
    type Hasher = <hashbrown::DefaultHashBuilder as BuildHasher>::Hasher;
115
116
    #[inline]
117
    fn build_hasher(&self) -> Self::Hasher {
118
        self.state.build_hasher()
119
    }
120
}