Fix crash with String subscript plus .endIndex (fix #991, fix #992)

This commit is contained in:
1024jp 2019-10-11 00:55:35 +09:00
parent 5d1a402819
commit 86bd48f0c3
9 changed files with 38 additions and 21 deletions

View File

@ -7,8 +7,8 @@ Change Log
### Fixes
- Fix a critical issue where the application could crash on launch under macOS 10.14.
- Fix an issue that the documents opened together were not opened as a sigle window with multiple tabs.
- Address a critical issue where the application could crash under macOS 10.14.
- Fix an issue that the documents opened together were not opened as a single window with multiple tabs.

View File

@ -96,7 +96,8 @@ final class ATSTypesetter: NSATSTypesetter {
let index = String.Index(utf16Offset: charIndex, in: string)
// check if the character is the first non-whitespace character after indent
for character in string[..<index].reversed() {
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
for character in string.substring(with: string.startIndex..<index).reversed() {
switch character {
case " ", "\t":
continue

View File

@ -143,7 +143,8 @@ extension EditorTextView {
let range = Range(self.selectedRange, in: self.string)!
let location = range.isEmpty ? self.string.startIndex : range.lowerBound
let lineRange = self.string.lineContentsRange(at: location)
viewController.sampleLine = String(self.string[lineRange])
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
viewController.sampleLine = self.string.substring(with: lineRange)
viewController.sampleFontName = self.font?.fontName
self.viewControllerForSheet?.presentAsSheet(viewController)

View File

@ -1535,7 +1535,8 @@ final class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, Multi
let range = Range(self.selectedRange, in: self.string)
else { return }
let substring = String(self.string[range])
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
let substring = self.string.substring(with: range)
let pattern = "\\b" + NSRegularExpression.escapedPattern(for: substring) + "\\b"
let regex = try! NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: self.string, range: self.string.nsRange)

View File

@ -100,10 +100,10 @@ extension StringProtocol where Self.Index == String.Index {
var detectedLineEnding: LineEnding? {
// We don't use `CharacterSet.newlines` because it contains more characters than we need.
guard
let range = self.rangeOfCharacter(from: LineEnding.characterSet),
let character = self[range].first // Swift treats "\r\n" also as a single character.
else { return nil }
guard let range = self.rangeOfCharacter(from: LineEnding.characterSet) else { return nil }
// Swift treats "\r\n" also as a single character.
let character = self[range.lowerBound]
return LineEnding(rawValue: character)
}

View File

@ -101,7 +101,10 @@ extension StringProtocol where Self.Index == String.Index {
var nestDepth = 0
var ignoredNestDepth = 0
let subsequence = self[beginIndex..<endIndex]
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
let subsequence = (endIndex == self.endIndex)
? self[beginIndex...]
: self[beginIndex..<endIndex]
for (index, character) in zip(subsequence.indices, subsequence).reversed() {
switch character {
@ -141,7 +144,10 @@ extension StringProtocol where Self.Index == String.Index {
var nestDepth = 0
var ignoredNestDepth = 0
let subsequence = self[self.index(after: beginIndex)..<endIndex]
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
let subsequence = (endIndex == self.endIndex)
? self[self.index(after: beginIndex)...]
: self[self.index(after: beginIndex)..<endIndex]
for (index, character) in zip(subsequence.indices, subsequence) {
switch character {

View File

@ -8,7 +8,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2018 1024jp
// © 2018-2019 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -44,7 +44,9 @@ extension String {
return self.ranges(pattern: "(?<=\\w)(?:[A-Z]|_\\w)")
.reversed()
.reduce(self.lowercased()) { (string, range) in
string.replacingCharacters(in: range, with: String(string[range].last!).uppercased())
let index = string.index(before: range.upperBound)
return string.replacingCharacters(in: range, with: string[index].uppercased())
}
}
@ -55,7 +57,9 @@ extension String {
return self.ranges(pattern: "(?:\\b|(?<=\\w)_)\\w")
.reversed()
.reduce(self) { (string, range) in
string.replacingCharacters(in: range, with: String(string[range].last!).uppercased())
let index = string.index(before: range.upperBound)
return string.replacingCharacters(in: range, with: string[index].uppercased())
}
}

View File

@ -65,10 +65,12 @@ extension StringProtocol where Self.Index == String.Index {
// workarond for the Swift 5 issue that removes BOM at the beginning (2019-05 Swift 5.0).
guard self.first != "\u{FEFF}" || self.count > 16 else {
let newlines = Set<Character>(["\n", "\r", "\r\n", "\u{0085}", "\u{2028}", "\u{2029}"])
let count = self[range].count { newlines.contains($0) } + 1
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
let substring = self.substring(with: range)
let count = substring.count { newlines.contains($0) } + 1
if !includingLastLineEnding,
let last = self[range].last,
let last = substring.last,
newlines.contains(last) {
return count - 1
}
@ -81,7 +83,8 @@ extension StringProtocol where Self.Index == String.Index {
}
if includingLastLineEnding,
let last = self[range].unicodeScalars.last,
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
let last = self.substring(with: range).unicodeScalars.last,
CharacterSet.newlines.contains(last)
{
count += 1

View File

@ -119,7 +119,8 @@ extension String {
guard !indentRange.isEmpty else { return 0 }
let indent = self[indentRange]
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
let indent = self.substring(with: indentRange)
let numberOfTabs = indent.components(separatedBy: "\t").count - 1
return numberOfTabs + ((indent.count - numberOfTabs) / tabWidth)
@ -136,7 +137,8 @@ extension String {
let column = self.distance(from: lineRange.lowerBound, to: index)
// count tab width
let beforeInsertion = self[lineRange.lowerBound..<index]
// workaround for NSBigMutableString + range subscript bug (2019-10 Xcode 11.1)
let beforeInsertion = self.substring(with: lineRange.lowerBound..<index)
let numberOfTabs = beforeInsertion.components(separatedBy: "\t").count - 1
return column + numberOfTabs * (tabWidth - 1)
@ -194,8 +196,7 @@ extension String {
guard
range.location >= targetLength,
let range = Range(targetRange, in: self),
self[range].allSatisfy({ $0 == " " })
(self as NSString).substring(with: targetRange).allSatisfy({ $0 == " " })
else { return nil }
return targetRange