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>
This commit is contained in:
Yonas Kolb
2026-03-05 17:07:57 +11:00
committed by GitHub
parent 50eb268b7d
commit 25841ee60d
4 changed files with 19 additions and 0 deletions
+1
View File
@@ -10,3 +10,4 @@ xcodegen.zip
xcodegen.artifactbundle.zip
.vscode/launch.json
DerivedData
.context
+4
View File
@@ -178,6 +178,10 @@ extension Project {
}
for source in target.sources {
if source.path.isEmpty {
errors.append(.emptySourcePath(target: target.name))
continue
}
let sourcePath = basePath + source.path
if !source.optional && !sourcePath.exists {
errors.append(.invalidTargetSource(target: target.name, source: sourcePath.string))
@@ -42,6 +42,7 @@ public struct SpecValidationError: Error, CustomStringConvertible {
case multipleDefaultTestPlans
case duplicateDependencies(target: String, dependencyReference: String)
case invalidPluginPackageReference(plugin: String, package: String)
case emptySourcePath(target: String)
public var description: String {
switch self {
@@ -109,6 +110,8 @@ public struct SpecValidationError: Error, CustomStringConvertible {
return "Target \(target.quoted) has the dependency \(dependencyReference.quoted) multiple times"
case let .invalidPluginPackageReference(plugin, package):
return "Plugin \(plugin) has invalid package reference \(package)"
case let .emptySourcePath(target):
return "Target \(target.quoted) has an empty source path entry"
}
}
}
@@ -320,6 +320,17 @@ class ProjectSpecTests: XCTestCase {
try expectValidationError(project, .invalidTargetSchemeConfigVariant(target: "target1", configVariant: "invalidVariant", configType: .debug))
}
$0.it("fails with empty source path") {
var project = baseProject
project.targets = [Target(
name: "target1",
type: .application,
platform: .iOS,
sources: ["", "validSource"]
)]
try expectValidationError(project, .emptySourcePath(target: "target1"))
}
$0.it("fails with invalid aggregate target") {
var project = baseProject
project.aggregateTargets = [AggregateTarget(