Skip to content

Commit 25841ee

Browse files
yonaskolbclaude
andauthored
Validate empty source paths to prevent project root inclusion (#1601)
* Add .context to .gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Validate empty source paths to prevent project root inclusion (#1595) Empty/null source entries (e.g. bare `-` in YAML) resolve to the project root, causing extreme memory usage. Add validation to reject them with a clear error message. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 50eb268 commit 25841ee

4 files changed

Lines changed: 19 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ xcodegen.zip
1010
xcodegen.artifactbundle.zip
1111
.vscode/launch.json
1212
DerivedData
13+
.context

Sources/ProjectSpec/SpecValidation.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ extension Project {
178178
}
179179

180180
for source in target.sources {
181+
if source.path.isEmpty {
182+
errors.append(.emptySourcePath(target: target.name))
183+
continue
184+
}
181185
let sourcePath = basePath + source.path
182186
if !source.optional && !sourcePath.exists {
183187
errors.append(.invalidTargetSource(target: target.name, source: sourcePath.string))

Sources/ProjectSpec/SpecValidationError.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public struct SpecValidationError: Error, CustomStringConvertible {
4242
case multipleDefaultTestPlans
4343
case duplicateDependencies(target: String, dependencyReference: String)
4444
case invalidPluginPackageReference(plugin: String, package: String)
45+
case emptySourcePath(target: String)
4546

4647
public var description: String {
4748
switch self {
@@ -109,6 +110,8 @@ public struct SpecValidationError: Error, CustomStringConvertible {
109110
return "Target \(target.quoted) has the dependency \(dependencyReference.quoted) multiple times"
110111
case let .invalidPluginPackageReference(plugin, package):
111112
return "Plugin \(plugin) has invalid package reference \(package)"
113+
case let .emptySourcePath(target):
114+
return "Target \(target.quoted) has an empty source path entry"
112115
}
113116
}
114117
}

Tests/ProjectSpecTests/ProjectSpecTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,17 @@ class ProjectSpecTests: XCTestCase {
320320
try expectValidationError(project, .invalidTargetSchemeConfigVariant(target: "target1", configVariant: "invalidVariant", configType: .debug))
321321
}
322322

323+
$0.it("fails with empty source path") {
324+
var project = baseProject
325+
project.targets = [Target(
326+
name: "target1",
327+
type: .application,
328+
platform: .iOS,
329+
sources: ["", "validSource"]
330+
)]
331+
try expectValidationError(project, .emptySourcePath(target: "target1"))
332+
}
333+
323334
$0.it("fails with invalid aggregate target") {
324335
var project = baseProject
325336
project.aggregateTargets = [AggregateTarget(

0 commit comments

Comments
 (0)