VoiceInk icon indicating copy to clipboard operation
VoiceInk copied to clipboard

Crash - Force unwrap of FileManager.urls() array subscript

Open ebrindley opened this issue 1 month ago • 0 comments

Crash - Force unwrap of FileManager.urls() array subscript

Labels: bug, crash, critical

Description

Multiple locations use FileManager.default.urls(for:in:)[0] with direct array subscript access without validation. While rare, this crashes if the array is empty due to sandboxing issues, permission problems, or filesystem corruption.

User Impact

  • Instant app crash on launch if Application Support directory is inaccessible

  • Complete inability to use the app on affected systems

  • No user-friendly error message explaining the problem

  • Can affect users with strict enterprise sandboxing or corrupted user profiles

Technical Details

File: VoiceInk/Whisper/WhisperState.swift

Line: 110


let appSupportDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]

    .appendingPathComponent("com.prakashjoshipax.VoiceInk")

Crash scenario: If urls(for:in:) returns an empty array (possible with strict sandboxing, permission issues, or corrupted user directory), accessing [0] triggers an immediate array out-of-bounds crash.

Reproduction

While difficult to reproduce in normal conditions, this can occur with:

  • Strict enterprise sandboxing policies

  • Corrupted user profile or home directory

  • Permission issues in containerized environments

  • macOS system file corruption

Recommended Fix

Replace lines 108-114 in VoiceInk/Whisper/WhisperState.swift:


init(modelContext: ModelContext, enhancementService: AIEnhancementService? = nil) {

    self.modelContext = modelContext

 

    guard let appSupportDirectory = FileManager.default.urls(

        for: .applicationSupportDirectory,

        in: .userDomainMask

    ).first else {

        fatalError("Cannot access Application Support directory. Please check system permissions.")

    }

 

    let voiceInkDirectory = appSupportDirectory.appendingPathComponent("com.prakashjoshipax.VoiceInk")

    self.modelsDirectory = voiceInkDirectory.appendingPathComponent("WhisperModels")

    self.recordingsDirectory = voiceInkDirectory.appendingPathComponent("Recordings")

 

    // ... rest of init

}

Testing

  1. Normal app launch should work identically

  2. Error message appears if directory is truly inaccessible (instead of silent crash)

  3. No crashes in any scenario

  4. Consider simulating permission issues during testing

ebrindley avatar Nov 12 '25 18:11 ebrindley