Skip to content

Commit 1b5c018

Browse files
author
Itai Ferber
committed
Account for Int vs. UInt8 in InlineData.hash(into:)
1 parent bb5ab74 commit 1b5c018

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

stdlib/public/Darwin/Foundation/Data.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -808,8 +808,22 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
808808

809809
@inlinable @inline(__always) // This should always be inlined into _Representation.hash(into:).
810810
func hash(into hasher: inout Hasher) {
811-
hasher.combine(length)
812-
Swift.withUnsafeBytes(of: bytes) { hasher.combine(bytes: $0) }
811+
// **NOTE**: this uses `count` (an Int) and NOT `length` (a UInt8)
812+
// Despite having the same value, they hash differently. InlineSlice and LargeSlice both use `count` (an Int); if you combine the same bytes but with `length` over `count`, you can get a different hash.
813+
//
814+
// This affects slices, which are InlineSlice and not InlineData:
815+
//
816+
// let d = Data([0xFF, 0xFF]) // InlineData
817+
// let s = Data([0, 0xFF, 0xFF]).dropFirst() // InlineSlice
818+
// assert(s == d)
819+
// assert(s.hashValue == d.hashValue)
820+
hasher.combine(count)
821+
822+
Swift.withUnsafeBytes(of: bytes) {
823+
// We have access to the full byte buffer here, but not all of it is meaningfully used (bytes past self.length may be garbage).
824+
let bytes = UnsafeRawBufferPointer(start: $0.baseAddress, count: self.count)
825+
hasher.combine(bytes: bytes)
826+
}
813827
}
814828
}
815829

@@ -1815,7 +1829,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
18151829
func hash(into hasher: inout Hasher) {
18161830
switch self {
18171831
case .empty:
1818-
hasher.combine(Int(bitPattern: CFHashBytes(nil, 0)))
1832+
hasher.combine(0)
18191833
case .inline(let inline):
18201834
inline.hash(into: &hasher)
18211835
case .slice(let slice):

0 commit comments

Comments
 (0)