Skip to content

Commit 0235a81

Browse files
authored
Merge pull request #23244 from itaiferber/data-underestimated-sequence-initializer-fix
Fix off-by-one when initializing Data with discontiguous, underestimated Sequences
2 parents 7f39a94 + 7ce6f84 commit 0235a81

File tree

2 files changed

+14
-10
lines changed

2 files changed

+14
-10
lines changed

stdlib/public/Darwin/Foundation/Data.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,9 +2084,8 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
20842084
// ... and append the rest byte-wise, buffering through an InlineData.
20852085
var buffer = InlineData()
20862086
while let element = iter.next() {
2087-
if buffer.count < buffer.capacity {
2088-
buffer.append(byte: element)
2089-
} else {
2087+
buffer.append(byte: element)
2088+
if buffer.count == buffer.capacity {
20902089
buffer.withUnsafeBytes { _representation.append(contentsOf: $0) }
20912090
buffer.count = 0
20922091
}
@@ -2378,9 +2377,8 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
23782377
// ... and append the rest byte-wise, buffering through an InlineData.
23792378
var buffer = InlineData()
23802379
while let element = iter.next() {
2381-
if buffer.count < buffer.capacity {
2382-
buffer.append(byte: element)
2383-
} else {
2380+
buffer.append(byte: element)
2381+
if buffer.count == buffer.capacity {
23842382
buffer.withUnsafeBytes { _representation.append(contentsOf: $0) }
23852383
buffer.count = 0
23862384
}

test/stdlib/TestData.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,10 +1260,13 @@ class TestData : TestDataSuper {
12601260

12611261
// If we append a sequence of elements larger than a single InlineData, the internal append here should buffer.
12621262
// We want to make sure that buffering in this way does not accidentally drop trailing elements on the floor.
1263-
d.append(contentsOf: 0x03...0x17)
1263+
d.append(contentsOf: 0x03...0x2F)
12641264
expectEqual(Data([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
12651265
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1266-
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17]), d)
1266+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1267+
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1268+
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1269+
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F]), d)
12671270
}
12681271

12691272
// This test is like test_appendingNonContiguousSequence_exactCount but uses a sequence which reports 0 for its `.underestimatedCount`.
@@ -1282,10 +1285,13 @@ class TestData : TestDataSuper {
12821285

12831286
// If we append a sequence of elements larger than a single InlineData, the internal append here should buffer.
12841287
// We want to make sure that buffering in this way does not accidentally drop trailing elements on the floor.
1285-
d.append(contentsOf: (0x03...0x17).makeIterator()) // `.makeIterator()` produces a sequence whose `.underestimatedCount` is 0.
1288+
d.append(contentsOf: (0x03...0x2F).makeIterator()) // `.makeIterator()` produces a sequence whose `.underestimatedCount` is 0.
12861289
expectEqual(Data([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
12871290
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1288-
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17]), d)
1291+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1292+
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1293+
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1294+
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F]), d)
12891295
}
12901296

12911297
func test_sequenceInitializers() {

0 commit comments

Comments
 (0)