33//! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order`
44//! feature of serde_json to use [`IndexMap`] instead.
55//!
6+ //! In builds without the `std` feature, `preserve_order` hashes keys with a
7+ //! deterministic fixed-seed hasher, as no entropy source is available in
8+ //! core/alloc. Such builds are not resistant to HashDoS attacks. Builds with
9+ //! `std` use [`RandomState`] and are unaffected.
10+ //!
611//! [`BTreeMap`]: std::collections::BTreeMap
712//! [`IndexMap`]: indexmap::IndexMap
13+ //! [`RandomState`]: std::collections::hash_map::RandomState
814
915use crate :: error:: Error ;
1016use crate :: value:: Value ;
@@ -32,15 +38,17 @@ pub struct Map<K, V> {
3238
3339#[ cfg( not( feature = "preserve_order" ) ) ]
3440type MapImpl < K , V > = BTreeMap < K , V > ;
35- #[ cfg( feature = "preserve_order" ) ]
41+ #[ cfg( all ( feature = "preserve_order" , feature = "std" ) ) ]
3642type MapImpl < K , V > = IndexMap < K , V > ;
43+ #[ cfg( all( feature = "preserve_order" , not( feature = "std" ) ) ) ]
44+ type MapImpl < K , V > = IndexMap < K , V , rustc_hash:: FxBuildHasher > ;
3745
3846impl Map < String , Value > {
3947 /// Makes a new empty Map.
4048 #[ inline]
4149 pub fn new ( ) -> Self {
4250 Map {
43- map : MapImpl :: new ( ) ,
51+ map : MapImpl :: default ( ) ,
4452 }
4553 }
4654
@@ -54,8 +62,10 @@ impl Map<String, Value> {
5462 let _ = capacity;
5563 BTreeMap :: new ( )
5664 } ,
57- #[ cfg( feature = "preserve_order" ) ]
65+ #[ cfg( all ( feature = "preserve_order" , feature = "std" ) ) ]
5866 map : IndexMap :: with_capacity ( capacity) ,
67+ #[ cfg( all( feature = "preserve_order" , not( feature = "std" ) ) ) ]
68+ map : IndexMap :: with_capacity_and_hasher ( capacity, rustc_hash:: FxBuildHasher ) ,
5969 }
6070 }
6171
@@ -386,9 +396,7 @@ impl Map<String, Value> {
386396impl Default for Map < String , Value > {
387397 #[ inline]
388398 fn default ( ) -> Self {
389- Map {
390- map : MapImpl :: new ( ) ,
391- }
399+ Map :: new ( )
392400 }
393401}
394402
0 commit comments