/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 | | } |