macOS: fix voice wake crash in trimmedAfterTrigger

Fixed an index out of bounds crash in VoiceWakeRuntime.trimmedAfterTrigger that occurred when processing voice transcripts. The issue was caused by attempting to subscript a string with an index that could exceed the string's endIndex when using indices from a lowercased version of the string.

Added a guard statement to check that the index is within bounds before attempting to subscript the string. If the index is out of bounds, the function continues to the next trigger instead of crashing.

Fixes the crash reported in crash.txt at line 743.
This commit is contained in:
Guillaume Nodet 2026-01-28 15:15:36 +01:00
parent d93f8ffc13
commit 479fc7450e
2 changed files with 15 additions and 0 deletions

View File

@ -740,6 +740,8 @@ actor VoiceWakeRuntime {
let token = trigger.lowercased().trimmingCharacters(in: .whitespacesAndNewlines)
guard !token.isEmpty, let range = lower.range(of: token) else { continue }
let after = range.upperBound
// Guard against index out of bounds when the trigger is at the end of the string
guard after <= text.endIndex else { continue }
let trimmed = text[after...].trimmingCharacters(in: .whitespacesAndNewlines)
return String(trimmed)
}

View File

@ -35,6 +35,19 @@ import Testing
#expect(VoiceWakeRuntime._testHasContentAfterTrigger(text, triggers: triggers))
}
@Test func trimsAfterTriggerHandlesTriggerAtEnd() {
let triggers = ["clawd"]
let text = "hey clawd"
#expect(VoiceWakeRuntime._testTrimmedAfterTrigger(text, triggers: triggers) == "")
}
@Test func trimsAfterTriggerHandlesEdgeCaseIndexBounds() {
// Regression test for crash when trigger range upperBound exceeds text.endIndex
let triggers = ["claude"]
let text = "claude"
#expect(VoiceWakeRuntime._testTrimmedAfterTrigger(text, triggers: triggers) == "")
}
@Test func gateRequiresGapBetweenTriggerAndCommand() {
let transcript = "hey clawd do thing"
let segments = makeSegments(