@@ -3098,15 +3098,19 @@ impl Hash for Path { |
|
|
3098 |
3098 |
let bytes = &bytes[prefix_len..]; |
3099 |
3099 |
|
3100 |
3100 |
let mut component_start = 0; |
3101 |
|
-let mut bytes_hashed = 0; |
|
3101 |
+// track some extra state to avoid prefix collisions. |
|
3102 |
+// ["foo", "bar"] and ["foobar"], will have the same payload bytes |
|
3103 |
+// but result in different chunk_bits |
|
3104 |
+let mut chunk_bits: usize = 0; |
3102 |
3105 |
|
3103 |
3106 |
for i in 0..bytes.len() { |
3104 |
3107 |
let is_sep = if verbatim { is_verbatim_sep(bytes[i]) } else { is_sep_byte(bytes[i]) }; |
3105 |
3108 |
if is_sep { |
3106 |
3109 |
if i > component_start { |
3107 |
3110 |
let to_hash = &bytes[component_start..i]; |
|
3111 |
+ chunk_bits = chunk_bits.wrapping_add(to_hash.len()); |
|
3112 |
+ chunk_bits = chunk_bits.rotate_right(2); |
3108 |
3113 |
h.write(to_hash); |
3109 |
|
- bytes_hashed += to_hash.len(); |
3110 |
3114 |
} |
3111 |
3115 |
|
3112 |
3116 |
// skip over separator and optionally a following CurDir item |
@@ -3127,11 +3131,12 @@ impl Hash for Path { |
|
|
3127 |
3131 |
|
3128 |
3132 |
if component_start < bytes.len() { |
3129 |
3133 |
let to_hash = &bytes[component_start..]; |
|
3134 |
+ chunk_bits = chunk_bits.wrapping_add(to_hash.len()); |
|
3135 |
+ chunk_bits = chunk_bits.rotate_right(2); |
3130 |
3136 |
h.write(to_hash); |
3131 |
|
- bytes_hashed += to_hash.len(); |
3132 |
3137 |
} |
3133 |
3138 |
|
3134 |
|
- h.write_usize(bytes_hashed); |
|
3139 |
+ h.write_usize(chunk_bits); |
3135 |
3140 |
} |
3136 |
3141 |
} |
3137 |
3142 |
|