Skip to content

Commit 4854530

Browse files
ktopley-applemoiseev
authored andcommitted
Fixes crash when DispatchData is created from an UnsafeBufferPointer<Uint8> with a nil address. (#7194)
Radar 29337927
1 parent 7c7a823 commit 4854530

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

stdlib/public/SDK/Dispatch/Data.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
4545
/// - parameter bytes: A pointer to the memory. It will be copied.
4646
/// - parameter count: The number of bytes to copy.
4747
public init(bytes buffer: UnsafeBufferPointer<UInt8>) {
48-
__wrapped = _swift_dispatch_data_create(
49-
buffer.baseAddress!, buffer.count, nil, _swift_dispatch_data_destructor_default()) as! __DispatchData
48+
__wrapped = buffer.baseAddress == nil ? _swift_dispatch_data_empty()
49+
: _swift_dispatch_data_create(buffer.baseAddress!, buffer.count, nil,
50+
_swift_dispatch_data_destructor_default()) as! __DispatchData
5051
}
5152

5253
/// Initialize a `Data` without copying the bytes.
@@ -56,9 +57,8 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
5657
/// - parameter deallocator: Specifies the mechanism to free the indicated buffer.
5758
public init(bytesNoCopy bytes: UnsafeBufferPointer<UInt8>, deallocator: Deallocator = .free) {
5859
let (q, b) = deallocator._deallocator
59-
60-
__wrapped = _swift_dispatch_data_create(
61-
bytes.baseAddress!, bytes.count, q, b) as! __DispatchData
60+
__wrapped = bytes.baseAddress == nil ? _swift_dispatch_data_empty()
61+
: _swift_dispatch_data_create(bytes.baseAddress!, bytes.count, q, b) as! __DispatchData
6262
}
6363

6464
internal init(data: __DispatchData) {

test/stdlib/Dispatch.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,25 @@ DispatchAPI.test("DispatchData.copyBytes") {
268268
expectEqual(destPtr[5], 0xFF)
269269
}
270270

271+
DispatchAPI.test("DispatchData.buffers") {
272+
let bytes = [UInt8(0), UInt8(1), UInt8(2), UInt8(2)]
273+
var ptr = UnsafeBufferPointer<UInt8>(start: bytes, count: bytes.count)
274+
var data = DispatchData(bytes: ptr)
275+
expectEqual(bytes.count, data.count)
276+
for i in 0..<data.count {
277+
expectEqual(data[i], bytes[i])
278+
}
279+
280+
data = DispatchData(bytesNoCopy: ptr, deallocator: .custom(nil, {}))
281+
expectEqual(bytes.count, data.count)
282+
for i in 0..<data.count {
283+
expectEqual(data[i], bytes[i])
284+
}
285+
286+
ptr = UnsafeBufferPointer<UInt8>(start: nil, count: 0)
287+
data = DispatchData(bytes: ptr)
288+
expectEqual(data.count, 0)
289+
290+
data = DispatchData(bytesNoCopy: ptr, deallocator: .custom(nil, {}))
291+
expectEqual(data.count, 0)
292+
}

0 commit comments

Comments
 (0)