This document contains a comprehensive analysis of bugs and potential issues found in the Shark codebase during code review.
Severity: High
Location: Sources/Shark/Extensions/String+Extensions.swift:58
return result.filter { !CharacterSet.forbidden.contains($0.unicodeScalars.first!) }Issue: Force unwrapping $0.unicodeScalars.first! can crash if the character has no unicode scalars. While this is rare, it's still a potential crash point.
Recommendation: Use safe unwrapping:
return result.filter { char in
guard let firstScalar = char.unicodeScalars.first else { return false }
return !CharacterSet.forbidden.contains(firstScalar)
}Severity: High
Locations:
Sources/Shark/Codegen/DataAsset.swift:4Sources/Shark/Codegen/ImageAsset.swift:6
Issue: The generated code includes force unwraps like NSDataAsset(name: "\(value)", bundle: bundle)!.data and UIImage(named:"\(value)", in: bundle, compatibleWith: nil)!. If assets are missing at runtime, these will crash the app.
Recommendation: Generate code with safe unwrapping and fallbacks or at minimum add documentation warning about missing assets.
Severity: High
Locations:
Sources/Shark/Extensions/Character+ExpressibleByArgument.swift:9Sources/Shark/Extensions/Character+ExpressibleByArgument.swift:18
self = argument.first!Issue: Force unwrapping argument.first! assumes the string is never empty, which could crash if an empty string is passed.
Recommendation: Add validation:
guard let first = argument.first else {
throw ValidationError("Character argument cannot be empty")
}
self = firstSeverity: Medium
Location: Sources/Shark/CLI/XcodeProjectHelper.swift:46
selectedTarget = project.targets[targetName]!Issue: This assumes the target exists after checking contains(targetName), but there's a race condition possibility or the check might not guarantee the key exists.
Recommendation: Use safe dictionary access:
guard let target = project.targets[targetName] else {
print("Target \(targetName) not found in project")
exit(EXIT_FAILURE)
}
selectedTarget = targetSeverity: Medium
Locations: Sources/Shark/CLI/XcodeProjectHelper.swift:102,108,111
let sharkFile = "\(options.outputPath):".data(using: .utf8)!
let dependency = " \(safeName)".data(using: .utf8)!
try fileHandle.write(contentsOf: "\n".data(using: .utf8)!)Issue: While UTF-8 encoding of these strings should never fail, force unwrapping is still risky practice.
Recommendation: Use safe conversion with error handling.
Severity: Medium
Location: Sources/Shark/CLI/Shark.swift:110
path.append("Shark.swift")Issue: Direct string appending without proper path joining could create malformed paths on different systems or with trailing slashes.
Recommendation: Use proper path APIs:
path = path.appendingPathComponent("Shark.swift")Severity: Medium
Location: Sources/Shark/Codegen/NestedEnumBuilder.swift:85-86
let contents = try String(contentsOfFile: pathToContentsJson)
if !contents.localizedCaseInsensitiveContains(#""provides-namespace" : true"#) {Issue: Uses naive string contains check instead of proper JSON parsing, which could give false positives/negatives with malformed JSON or different formatting.
Recommendation: Parse JSON properly and check the actual boolean value.
Severity: Medium
Locations: Sources/Shark/CLI/XcodeProjectHelper.swift:54,59,65,72
exit(EXIT_FAILURE)Issue: Multiple exit(EXIT_FAILURE) calls terminate the entire process instead of throwing proper errors that could be handled by calling code.
Recommendation: Replace with proper error throwing for better composability and testing.
The codebase has several critical issues primarily around force unwrapping that could lead to runtime crashes. The most concerning are:
- Force unwraps in the generated asset access code that will crash if assets are missing
- Force unwraps in string processing that could crash on edge cases
- Unsafe character handling in argument parsing
- Immediate: Replace all force unwraps with safe unwrapping and proper error handling
- Short term: Use proper path manipulation APIs instead of string concatenation
- Medium term: Replace
exit()calls with proper error throwing for better composability - Long term: Add comprehensive error handling and validation throughout the codebase
- Add unit tests for edge cases (empty strings, missing files, malformed JSON)
- Test with projects that have missing assets to verify generated code behavior
- Test path handling on different operating systems
- Add integration tests for various Xcode project configurations