Skip to content

Commit 4f52020

Browse files
committed
Adjust Status Parsing to Better Handle Null Chars
1 parent 5f48f0a commit 4f52020

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

CodeEdit/Features/SourceControl/Client/GitClient+Status.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,25 @@ extension GitClient {
3636
/// - Throws: Can throw ``GitClient/GitClientError`` errors if it finds unexpected output.
3737
func getStatus() async throws -> Status {
3838
let output = try await run("status -z --porcelain=2 -u")
39+
return try parseStatusString(output)
40+
}
41+
42+
/// Parses a status string from ``getStatus()`` and returns a ``Status`` object if possible.
43+
/// - Parameter output: The git output from running `status`. Expects a porcelain v2 string.
44+
/// - Returns: A status object if parseable.
45+
func parseStatusString(_ output: borrowing String) throws -> Status {
46+
let endsInNull = output.last == Character(UnicodeScalar(0))
47+
let endIndex: String.Index
48+
if endsInNull && output.count > 1 {
49+
endIndex = output.index(before: output.endIndex)
50+
} else {
51+
endIndex = output.endIndex
52+
}
3953

4054
var status = Status(changedFiles: [], unmergedChanges: [], untrackedFiles: [])
4155

4256
var index = output.startIndex
43-
while index < output.endIndex {
57+
while index < endIndex {
4458
let typeIndex = index
4559

4660
// Move ahead no matter what.
@@ -100,7 +114,11 @@ extension GitClient {
100114
}
101115
index = newIndex
102116
}
103-
index = output.index(after: index)
117+
defer {
118+
if index < output.index(before: output.endIndex) {
119+
index = output.index(after: index)
120+
}
121+
}
104122
return output[startIndex..<index]
105123
}
106124

@@ -147,7 +165,8 @@ extension GitClient {
147165
try moveToNextSpace(from: &index, output: output)
148166
}
149167
try moveOneChar(from: &index, output: output)
150-
let filename = String(try substringToNextNull(from: &index, output: output))
168+
let substring = try substringToNextNull(from: &index, output: output)
169+
let filename = String(substring)
151170
return GitChangedFile(
152171
status: status,
153172
stagedStatus: stagedStatus,

0 commit comments

Comments
 (0)