Skip to content

Commit bf56b09

Browse files
[SR-6361] Fix Data.withUnsafeMutableBytes() for slices with length < range.lowerBound
1 parent a8a4752 commit bf56b09

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

stdlib/public/SDK/Foundation/Data.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,20 +198,20 @@ public final class _DataStorage {
198198
switch _backing {
199199
case .swift: fallthrough
200200
case .mutable:
201-
return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length - range.lowerBound)))
201+
return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length)))
202202
case .customMutableReference(let d):
203203
let len = d.length
204-
return try apply(UnsafeMutableRawBufferPointer(start: d.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len - range.lowerBound)))
204+
return try apply(UnsafeMutableRawBufferPointer(start: d.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len)))
205205
case .immutable(let d):
206206
let data = d.mutableCopy() as! NSMutableData
207207
_backing = .mutable(data)
208208
_bytes = data.mutableBytes
209-
return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length - range.lowerBound)))
209+
return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length)))
210210
case .customReference(let d):
211211
let data = d.mutableCopy() as! NSMutableData
212212
_backing = .customMutableReference(data)
213213
let len = data.length
214-
return try apply(UnsafeMutableRawBufferPointer(start: data.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len - range.lowerBound)))
214+
return try apply(UnsafeMutableRawBufferPointer(start: data.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len)))
215215
}
216216
}
217217

test/stdlib/TestData.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3677,6 +3677,50 @@ class TestData : TestDataSuper {
36773677
let h3 = d3.hashValue
36783678
expectEqual(h1, h3)
36793679
}
3680+
3681+
func test_validateMutation_slice_withUnsafeMutableBytes_lengthLessThanLowerBound() {
3682+
var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<6]
3683+
data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
3684+
ptr.advanced(by: 1).pointee = 0xFF
3685+
}
3686+
expectEqual(data, Data(bytes: [4, 0xFF]))
3687+
}
3688+
3689+
func test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() {
3690+
var data = Data(referencing: NSData(bytes: "hello world", length: 11))[4..<6]
3691+
data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
3692+
ptr.advanced(by: 1).pointee = 0xFF
3693+
}
3694+
expectEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
3695+
}
3696+
3697+
func test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() {
3698+
var base = Data(referencing: NSData(bytes: "hello world", length: 11))
3699+
base.append(contentsOf: [1, 2, 3, 4, 5, 6])
3700+
var data = base[4..<6]
3701+
data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
3702+
ptr.advanced(by: 1).pointee = 0xFF
3703+
}
3704+
expectEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
3705+
}
3706+
3707+
func test_validateMutation_slice_customBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() {
3708+
var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<6]
3709+
data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
3710+
ptr.advanced(by: 1).pointee = 0xFF
3711+
}
3712+
expectEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
3713+
}
3714+
3715+
func test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() {
3716+
var base = Data(referencing: AllOnesData(length: 1))
3717+
base.count = 10
3718+
var data = base[4..<6]
3719+
data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
3720+
ptr.advanced(by: 1).pointee = 0xFF
3721+
}
3722+
expectEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
3723+
}
36803724
}
36813725

36823726
#if !FOUNDATION_XCTEST
@@ -3988,6 +4032,11 @@ DataTests.test("test_sliceHash") { TestData().test_sliceHash() }
39884032
DataTests.test("test_slice_resize_growth") { TestData().test_slice_resize_growth() }
39894033
DataTests.test("test_sliceEnumeration") { TestData().test_sliceEnumeration() }
39904034
DataTests.test("test_hashEmptyData") { TestData().test_hashEmptyData() }
4035+
DataTests.test("test_validateMutation_slice_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_withUnsafeMutableBytes_lengthLessThanLowerBound() }
4036+
DataTests.test("test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
4037+
DataTests.test("test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
4038+
DataTests.test("test_validateMutation_slice_customBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_customBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
4039+
DataTests.test("test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
39914040

39924041
// XCTest does not have a crash detection, whereas lit does
39934042
DataTests.test("bounding failure subdata") {

0 commit comments

Comments
 (0)