@@ -165,9 +165,19 @@ mod io_extras {
165165mod prelude {
166166 #[ cfg( feature = "hashbrown" ) ]
167167 extern crate hashbrown;
168+ #[ cfg( feature = "ahash" ) ]
169+ extern crate ahash;
168170
169171 pub use alloc:: { vec, vec:: Vec , string:: String , collections:: VecDeque , boxed:: Box } ;
170172
173+ pub use alloc:: borrow:: ToOwned ;
174+ pub use alloc:: string:: ToString ;
175+
176+ // For no-std builds, we need to use hashbrown, however, by default, it doesn't randomize the
177+ // hashing and is vulnerable to HashDoS attacks. Thus, when not fuzzing, we use its default
178+ // ahash hashing algorithm but randomize, opting to not randomize when fuzzing to avoid false
179+ // positive branch coverage.
180+
171181 #[ cfg( not( feature = "hashbrown" ) ) ]
172182 mod std_hashtables {
173183 pub ( crate ) use std:: collections:: { HashMap , HashSet , hash_map} ;
@@ -181,32 +191,71 @@ mod prelude {
181191 pub ( crate ) use std_hashtables:: * ;
182192
183193 #[ cfg( feature = "hashbrown" ) ]
184- mod hashbrown_tables {
185- pub ( crate ) use hashbrown:: { HashMap , HashSet , hash_map} ;
194+ pub ( crate ) use self :: hashbrown:: hash_map;
195+
196+ #[ cfg( all( feature = "hashbrown" , fuzzing) ) ]
197+ mod nonrandomized_hashbrown {
198+ pub ( crate ) use hashbrown:: { HashMap , HashSet } ;
186199
187200 pub ( crate ) type OccupiedHashMapEntry < ' a , K , V > =
188- hashbrown:: hash_map:: OccupiedEntry < ' a , K , V , hash_map:: DefaultHashBuilder > ;
201+ hashbrown:: hash_map:: OccupiedEntry < ' a , K , V , hashbrown :: hash_map:: DefaultHashBuilder > ;
189202 pub ( crate ) type VacantHashMapEntry < ' a , K , V > =
190- hashbrown:: hash_map:: VacantEntry < ' a , K , V , hash_map:: DefaultHashBuilder > ;
203+ hashbrown:: hash_map:: VacantEntry < ' a , K , V , hashbrown :: hash_map:: DefaultHashBuilder > ;
191204 }
192- #[ cfg( feature = "hashbrown" ) ]
193- pub ( crate ) use hashbrown_tables :: * ;
205+ #[ cfg( all ( feature = "hashbrown" , fuzzing ) ) ]
206+ pub ( crate ) use nonrandomized_hashbrown :: * ;
194207
195- pub ( crate ) fn new_hash_map < K : core:: hash:: Hash + Eq , V > ( ) -> HashMap < K , V > { HashMap :: new ( ) }
196- pub ( crate ) fn hash_map_with_capacity < K : core:: hash:: Hash + Eq , V > ( cap : usize ) -> HashMap < K , V > {
197- HashMap :: with_capacity ( cap)
198- }
199208
200- pub ( crate ) fn new_hash_set < K : core:: hash:: Hash + Eq > ( ) -> HashSet < K > { HashSet :: new ( ) }
201- pub ( crate ) fn hash_set_with_capacity < K : core:: hash:: Hash + Eq > ( cap : usize ) -> HashSet < K > {
202- HashSet :: with_capacity ( cap)
209+ #[ cfg( all( feature = "hashbrown" , not( fuzzing) ) ) ]
210+ mod randomized_hashtables {
211+ use super :: * ;
212+ use ahash:: RandomState ;
213+
214+ pub ( crate ) type HashMap < K , V > = hashbrown:: HashMap < K , V , RandomState > ;
215+ pub ( crate ) type HashSet < K > = hashbrown:: HashSet < K , RandomState > ;
216+
217+ pub ( crate ) type OccupiedHashMapEntry < ' a , K , V > =
218+ hashbrown:: hash_map:: OccupiedEntry < ' a , K , V , RandomState > ;
219+ pub ( crate ) type VacantHashMapEntry < ' a , K , V > =
220+ hashbrown:: hash_map:: VacantEntry < ' a , K , V , RandomState > ;
221+
222+ pub ( crate ) fn new_hash_map < K , V > ( ) -> HashMap < K , V > {
223+ HashMap :: with_hasher ( RandomState :: new ( ) )
224+ }
225+ pub ( crate ) fn hash_map_with_capacity < K , V > ( cap : usize ) -> HashMap < K , V > {
226+ HashMap :: with_capacity_and_hasher ( cap, RandomState :: new ( ) )
227+ }
228+
229+ pub ( crate ) fn new_hash_set < K > ( ) -> HashSet < K > {
230+ HashSet :: with_hasher ( RandomState :: new ( ) )
231+ }
232+ pub ( crate ) fn hash_set_with_capacity < K > ( cap : usize ) -> HashSet < K > {
233+ HashSet :: with_capacity_and_hasher ( cap, RandomState :: new ( ) )
234+ }
235+ pub ( crate ) fn hash_set_from_iter < K : core:: hash:: Hash + Eq , I : IntoIterator < Item =K > > ( iter : I ) -> HashSet < K > {
236+ HashSet :: from_iter ( iter)
237+ }
203238 }
204- pub ( crate ) fn hash_set_from_iter < K : core:: hash:: Hash + Eq , I : IntoIterator < Item = K > > ( iter : I ) -> HashSet < K > {
205- HashSet :: from_iter ( iter)
239+
240+ #[ cfg( any( not( feature = "hashbrown" ) , fuzzing) ) ]
241+ mod randomized_hashtables {
242+ use super :: * ;
243+
244+ pub ( crate ) fn new_hash_map < K , V > ( ) -> HashMap < K , V > { HashMap :: new ( ) }
245+ pub ( crate ) fn hash_map_with_capacity < K , V > ( cap : usize ) -> HashMap < K , V > {
246+ HashMap :: with_capacity ( cap)
247+ }
248+
249+ pub ( crate ) fn new_hash_set < K > ( ) -> HashSet < K > { HashSet :: new ( ) }
250+ pub ( crate ) fn hash_set_with_capacity < K > ( cap : usize ) -> HashSet < K > {
251+ HashSet :: with_capacity ( cap)
252+ }
253+ pub ( crate ) fn hash_set_from_iter < K : core:: hash:: Hash + Eq , I : IntoIterator < Item =K > > ( iter : I ) -> HashSet < K > {
254+ HashSet :: from_iter ( iter)
255+ }
206256 }
207257
208- pub use alloc:: borrow:: ToOwned ;
209- pub use alloc:: string:: ToString ;
258+ pub ( crate ) use randomized_hashtables:: * ;
210259}
211260
212261#[ cfg( all( not( ldk_bench) , feature = "backtrace" , feature = "std" , test) ) ]
0 commit comments