Skip to content

Commit

Permalink
Merge pull request #5603 from JaSpa/CharacterSet-ClosedRange
Browse files Browse the repository at this point in the history
  • Loading branch information
swift-ci committed Nov 3, 2016
2 parents 2b73a9a + d5e1819 commit 84f7b1d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
13 changes: 7 additions & 6 deletions stdlib/public/SDK/Foundation/CharacterSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ private func _utfRangeToNSRange(_ inRange : Range<UnicodeScalar>) -> NSRange {
return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value))
}

private func _utfRangeToNSRange(_ inRange : ClosedRange<UnicodeScalar>) -> NSRange {
return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value + 1))
}

internal final class _SwiftNSCharacterSet : _SwiftNativeNSCharacterSet, _SwiftNativeFoundationType {
internal typealias ImmutableType = NSCharacterSet
internal typealias MutableType = NSMutableCharacterSet
Expand Down Expand Up @@ -104,8 +108,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
///
/// It is the caller's responsibility to ensure that the values represent valid `UnicodeScalar` values, if that is what is desired.
public init(charactersIn range: ClosedRange<UnicodeScalar>) {
let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
_wrapped = _SwiftNSCharacterSet(immutableObject: NSCharacterSet(range: _utfRangeToNSRange(halfOpenRange)))
_wrapped = _SwiftNSCharacterSet(immutableObject: NSCharacterSet(range: _utfRangeToNSRange(range)))
}

/// Initialize with the characters in the given string.
Expand Down Expand Up @@ -292,8 +295,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
///
/// It is the caller's responsibility to ensure that the values represent valid `UnicodeScalar` values, if that is what is desired.
public mutating func insert(charactersIn range: ClosedRange<UnicodeScalar>) {
let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
let nsRange = _utfRangeToNSRange(halfOpenRange)
let nsRange = _utfRangeToNSRange(range)
_applyUnmanagedMutation {
$0.addCharacters(in: nsRange)
}
Expand All @@ -309,8 +311,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb

/// Remove a closed range of integer values from the `CharacterSet`.
public mutating func remove(charactersIn range: ClosedRange<UnicodeScalar>) {
let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
let nsRange = _utfRangeToNSRange(halfOpenRange)
let nsRange = _utfRangeToNSRange(range)
_applyUnmanagedMutation {
$0.removeCharacters(in: nsRange)
}
Expand Down
14 changes: 13 additions & 1 deletion test/stdlib/TestCharacterSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,19 @@ class TestCharacterSet : TestCharacterSetSuper {
let result = testString.trimmingCharacters(in: asciiLowercase)
expectEqual(result, expected)
}


func testClosedRanges_SR_2988() {
// "CharacterSet.insert(charactersIn: ClosedRange) crashes on a closed ClosedRange<UnicodeScalar> containing U+D7FF"
let problematicChar = UnicodeScalar(0xD7FF)!
let range = capitalA...problematicChar
var characters = CharacterSet(charactersIn: range) // this should not crash
expectTrue(characters.contains(problematicChar))
characters.remove(charactersIn: range) // this should not crash
expectTrue(!characters.contains(problematicChar))
characters.insert(charactersIn: range) // this should not crash
expectTrue(characters.contains(problematicChar))
}

func testInsertAndRemove() {
var asciiUppercase = CharacterSet(charactersIn: UnicodeScalar(0x41)!...UnicodeScalar(0x5A)!)
expectTrue(asciiUppercase.contains(UnicodeScalar(0x49)!))
Expand Down

0 comments on commit 84f7b1d

Please sign in to comment.