Skip to content

Commit e79af69

Browse files
committed
[Foundation] replaceSubrange in the cases of immutable and mutable backing stores should recalculate length per the reference backing store change and not the length of the replacement
1 parent 0e7d41d commit e79af69

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

stdlib/public/SDK/Foundation/Data.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,12 +480,12 @@ public final class _DataStorage {
480480
let data = d.mutableCopy() as! NSMutableData
481481
data.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
482482
_backing = .mutable(data)
483-
_length = replacementLength
483+
_length = data.length
484484
_bytes = data.mutableBytes
485485
case .mutable(let d):
486486
d.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
487487
_backing = .mutable(d)
488-
_length = replacementLength
488+
_length = d.length
489489
_bytes = d.mutableBytes
490490
case .customReference(let d):
491491
let data = d.mutableCopy() as! NSMutableData

test/stdlib/TestData.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,35 @@ class TestData : TestDataSuper {
11791179
let expected = Data(bytes: [9, 8, 7, 6, 5, 4, 3, 2, 1])
11801180
expectEqual(expected, reversedData)
11811181
}
1182+
1183+
func test_replaceSubrangeReferencingMutable() {
1184+
let mdataObj = NSMutableData(bytes: [0x01, 0x02, 0x03, 0x04], length: 4)
1185+
var data = Data(referencing: mdataObj)
1186+
let expected = data.count
1187+
data.replaceSubrange(4 ..< 4, with: Data(bytes: []))
1188+
expectEqual(expected, data.count)
1189+
data.replaceSubrange(4 ..< 4, with: Data(bytes: []))
1190+
expectEqual(expected, data.count)
1191+
}
1192+
1193+
func test_replaceSubrangeReferencingImmutable() {
1194+
let dataObj = NSData(bytes: [0x01, 0x02, 0x03, 0x04], length: 4)
1195+
var data = Data(referencing: dataObj)
1196+
let expected = data.count
1197+
data.replaceSubrange(4 ..< 4, with: Data(bytes: []))
1198+
expectEqual(expected, data.count)
1199+
data.replaceSubrange(4 ..< 4, with: Data(bytes: []))
1200+
expectEqual(expected, data.count)
1201+
}
1202+
1203+
func test_replaceSubrangeFromBridged() {
1204+
var data = NSData(bytes: [0x01, 0x02, 0x03, 0x04], length: 4) as Data
1205+
let expected = data.count
1206+
data.replaceSubrange(4 ..< 4, with: Data(bytes: []))
1207+
expectEqual(expected, data.count)
1208+
data.replaceSubrange(4 ..< 4, with: Data(bytes: []))
1209+
expectEqual(expected, data.count)
1210+
}
11821211
}
11831212

11841213
#if !FOUNDATION_XCTEST
@@ -1243,6 +1272,9 @@ DataTests.test("test_sliceOfSliceViaRangeExpression") { TestData().test_sliceOfS
12431272
DataTests.test("test_appendingSlices") { TestData().test_appendingSlices() }
12441273
DataTests.test("test_sequenceInitializers") { TestData().test_sequenceInitializers() }
12451274
DataTests.test("test_reversedDataInit") { TestData().test_reversedDataInit() }
1275+
DataTests.test("test_replaceSubrangeReferencingMutable") { TestData().test_replaceSubrangeReferencingMutable() }
1276+
DataTests.test("test_replaceSubrangeReferencingImmutable") { TestData().test_replaceSubrangeReferencingImmutable() }
1277+
DataTests.test("test_replaceSubrangeFromBridged") { TestData().test_replaceSubrangeFromBridged() }
12461278

12471279

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

0 commit comments

Comments
 (0)