Skip to content

Commit 26b3c55

Browse files
committed
[SR-14886] Check wCSIA before copying byte by byte.
1 parent b6107b4 commit 26b3c55

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

stdlib/public/core/UnsafeRawBufferPointer.swift.gyb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,16 @@ extension Unsafe${Mutable}RawBufferPointer {
412412
guard let position = _position else {
413413
return
414414
}
415+
416+
if source.withContiguousStorageIfAvailable({
417+
(buffer: UnsafeBufferPointer<C.Element>) -> Void in
418+
if let base = buffer.baseAddress {
419+
position.copyMemory(from: base, byteCount: buffer.count)
420+
}
421+
}) != nil {
422+
return
423+
}
424+
415425
for (index, byteValue) in source.enumerated() {
416426
position.storeBytes(
417427
of: byteValue, toByteOffset: index, as: UInt8.self)

test/stdlib/UnsafeRawBufferPointer.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,19 @@ UnsafeRawBufferPointerTestSuite.test("copyMemory.overflow") {
421421
from: UnsafeRawBufferPointer(buffer))
422422
}
423423

424+
// Use copyBytes without contiguous storage
425+
UnsafeRawBufferPointerTestSuite.test("copyBytes.withoutContiguouseStorage") {
426+
let ranges: [Range<UInt8>] = [0..<2, 1..<3, 2..<4, 3..<5]
427+
var array = [UInt8](repeating: 0, count: 2)
428+
for range in ranges {
429+
array.withUnsafeMutableBytes { byte in
430+
byte.copyBytes(from: range)
431+
}
432+
expectEqual(array.count, range.count)
433+
expectEqual(array, Array(range))
434+
}
435+
}
436+
424437
UnsafeRawBufferPointerTestSuite.test("copyBytes.sequence.overflow") {
425438
var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: 3, alignment: MemoryLayout<UInt>.alignment)
426439
defer { buffer.deallocate() }

0 commit comments

Comments
 (0)