Skip to content

Commit 7ae394e

Browse files
authored
Merge pull request #707 from parkera/sr2988
2 parents 4a9355f + c47af1d commit 7ae394e

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

Foundation/CharacterSet.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
private func _utfRangeToNSRange(_ inRange : Range<UnicodeScalar>) -> NSRange {
1414
return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value))
1515
}
16+
17+
private func _utfRangeToNSRange(_ inRange : ClosedRange<UnicodeScalar>) -> NSRange {
18+
return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value + 1))
19+
}
1620

1721
internal final class _SwiftNSCharacterSet : NSCharacterSet, _SwiftNativeFoundationType {
1822
internal typealias ImmutableType = NSCharacterSet
@@ -129,8 +133,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
129133
///
130134
/// It is the caller's responsibility to ensure that the values represent valid `UnicodeScalar` values, if that is what is desired.
131135
public init(charactersIn range: ClosedRange<UnicodeScalar>) {
132-
let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
133-
_wrapped = _SwiftNSCharacterSet(immutableObject: NSCharacterSet(range: _utfRangeToNSRange(halfOpenRange)))
136+
_wrapped = _SwiftNSCharacterSet(immutableObject: NSCharacterSet(range: _utfRangeToNSRange(range)))
134137
}
135138

136139
/// Initialize with the characters in the given string.
@@ -320,8 +323,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
320323
///
321324
/// It is the caller's responsibility to ensure that the values represent valid `UnicodeScalar` values, if that is what is desired.
322325
public mutating func insert(charactersIn range: ClosedRange<UnicodeScalar>) {
323-
let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
324-
let nsRange = _utfRangeToNSRange(halfOpenRange)
326+
let nsRange = _utfRangeToNSRange(range)
325327
_applyUnmanagedMutation {
326328
$0.addCharacters(in: nsRange)
327329
}
@@ -337,8 +339,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
337339

338340
/// Remove a closed range of integer values from the `CharacterSet`.
339341
public mutating func remove(charactersIn range: ClosedRange<UnicodeScalar>) {
340-
let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
341-
let nsRange = _utfRangeToNSRange(halfOpenRange)
342+
let nsRange = _utfRangeToNSRange(range)
342343
_applyUnmanagedMutation {
343344
$0.removeCharacters(in: nsRange)
344345
}

TestFoundation/TestNSCharacterSet.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class TestNSCharacterSet : XCTestCase {
2828
("testRanges", testRanges),
2929
("testInsertAndRemove", testInsertAndRemove),
3030
("testBasics", testBasics),
31-
31+
("testClosedRanges_SR_2988", testClosedRanges_SR_2988),
3232
("test_Predefines", test_Predefines),
3333
("test_Range", test_Range),
3434
("test_String", test_String),
@@ -223,6 +223,18 @@ class TestNSCharacterSet : XCTestCase {
223223
}
224224
}
225225

226+
func testClosedRanges_SR_2988() {
227+
// "CharacterSet.insert(charactersIn: ClosedRange) crashes on a closed ClosedRange<UnicodeScalar> containing U+D7FF"
228+
let problematicChar = UnicodeScalar(0xD7FF)!
229+
let range = capitalA...problematicChar
230+
var characters = CharacterSet(charactersIn: range) // this should not crash
231+
XCTAssertTrue(characters.contains(problematicChar))
232+
characters.remove(charactersIn: range) // this should not crash
233+
XCTAssertTrue(!characters.contains(problematicChar))
234+
characters.insert(charactersIn: range) // this should not crash
235+
XCTAssertTrue(characters.contains(problematicChar))
236+
}
237+
226238
func test_Bitmap() {
227239

228240
}

0 commit comments

Comments
 (0)