Skip to content

Commit a2e34a2

Browse files
authored
Merge pull request #12511 from phausler/swift-4.0-branch-empty_data_hashing_fix
Ensure that hashing data with zero bytes avoids empty allocations and fix bridged empty data hashes from de-referencing null values
2 parents 68da0c4 + 007f7d2 commit a2e34a2

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

stdlib/public/SDK/Foundation/Data.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,9 +1627,11 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
16271627
public var hashValue: Int {
16281628
var hashValue = 0
16291629
let hashRange: Range<Int> = _sliceRange.lowerBound..<Swift.min(_sliceRange.lowerBound + 80, _sliceRange.upperBound)
1630-
_withStackOrHeapBuffer(hashRange.count) { buffer in
1631-
_backing.withUnsafeBytes(in: hashRange) {
1632-
memcpy(buffer.pointee.memory, $0.baseAddress!, hashRange.count)
1630+
_withStackOrHeapBuffer(hashRange.count + 1) { buffer in
1631+
if hashRange.count > 0 {
1632+
_backing.withUnsafeBytes(in: hashRange) {
1633+
memcpy(buffer.pointee.memory, $0.baseAddress!, hashRange.count)
1634+
}
16331635
}
16341636
hashValue = Int(bitPattern: CFHashBytes(buffer.pointee.memory.assumingMemoryBound(to: UInt8.self), hashRange.count))
16351637
}

test/stdlib/TestData.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,6 +3656,20 @@ class TestData : TestDataSuper {
36563656
expectEqual(Data(bytes: [0, 1, 2, 3, 4]), regionData[1]) //passes
36573657
expectEqual(Data(bytes: [0]), regionData[2]) //fails
36583658
}
3659+
3660+
func test_hashEmptyData() {
3661+
let d1 = Data()
3662+
let h1 = d1.hashValue
3663+
3664+
let d2 = NSData() as Data
3665+
let h2 = d2.hashValue
3666+
expectEqual(h1, h2)
3667+
3668+
let data = Data(bytes: [0, 1, 2, 3, 4, 5, 6])
3669+
let d3 = data[4..<4]
3670+
let h3 = d3.hashValue
3671+
expectEqual(h1, h3)
3672+
}
36593673
}
36603674

36613675
#if !FOUNDATION_XCTEST
@@ -3966,6 +3980,7 @@ DataTests.test("test_validateMutation_slice_cow_customMutableBacking_replaceSubr
39663980
DataTests.test("test_sliceHash") { TestData().test_sliceHash() }
39673981
DataTests.test("test_slice_resize_growth") { TestData().test_slice_resize_growth() }
39683982
DataTests.test("test_sliceEnumeration") { TestData().test_sliceEnumeration() }
3983+
DataTests.test("test_hashEmptyData") { TestData().test_hashEmptyData() }
39693984

39703985

39713986
// XCTest does not have a crash detection, whereas lit does

0 commit comments

Comments
 (0)