Coverage Report

Created: 2025-12-09 07:28

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
2.82M
    fn default() -> RandomState {
15
2.82M
        RandomState(RandomStateImpl::default())
16
2.82M
    }
17
}
18
19
impl BuildHasher for RandomState {
20
    type Hasher = RandomStateHasher;
21
22
    #[inline]
23
2.64M
    fn build_hasher(&self) -> RandomStateHasher {
24
2.64M
        RandomStateHasher(self.0.build_hasher())
25
2.64M
    }
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
2.64M
    fn finish(&self) -> u64 {
34
2.64M
        self.0.finish()
35
2.64M
    }
36
    #[inline]
37
889k
    fn write(&mut self, bytes: &[u8]) {
38
889k
        self.0.write(bytes)
39
889k
    }
40
    #[inline]
41
2.77M
    fn write_u8(&mut self, i: u8) {
42
2.77M
        self.0.write_u8(i)
43
2.77M
    }
44
    #[inline]
45
    fn write_u16(&mut self, i: u16) {
46
        self.0.write_u16(i)
47
    }
48
    #[inline]
49
4.66M
    fn write_u32(&mut self, i: u32) {
50
4.66M
        self.0.write_u32(i)
51
4.66M
    }
52
    #[inline]
53
    fn write_u64(&mut self, i: u64) {
54
        self.0.write_u64(i)
55
    }
56
    #[inline]
57
    fn write_u128(&mut self, i: u128) {
58
        self.0.write_u128(i)
59
    }
60
    #[inline]
61
1.24M
    fn write_usize(&mut self, i: usize) {
62
1.24M
        self.0.write_usize(i)
63
1.24M
    }
64
    #[inline]
65
    fn write_i8(&mut self, i: i8) {
66
        self.0.write_i8(i)
67
    }
68
    #[inline]
69
    fn write_i16(&mut self, i: i16) {
70
        self.0.write_i16(i)
71
    }
72
    #[inline]
73
    fn write_i32(&mut self, i: i32) {
74
        self.0.write_i32(i)
75
    }
76
    #[inline]
77
    fn write_i64(&mut self, i: i64) {
78
        self.0.write_i64(i)
79
    }
80
    #[inline]
81
    fn write_i128(&mut self, i: i128) {
82
        self.0.write_i128(i)
83
    }
84
    #[inline]
85
5.46M
    fn write_isize(&mut self, i: isize) {
86
5.46M
        self.0.write_isize(i)
87
5.46M
    }
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
}