Skip to content

Commit b0d8867

Browse files
authored
Do not crash on invalid file URLs (#5795)
rdar://100738993
1 parent 239f317 commit b0d8867

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

Sources/PackageLoading/ManifestJSONParser.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ enum ManifestJSONParser {
231231
"file:// URLs with hostnames are not supported, are you missing a '/'?", diagnosticFile: nil
232232
)
233233
}
234-
return AbsolutePath(location).pathString
234+
return try AbsolutePath(validating: location).pathString
235235
} else if parseScheme(dependencyLocation) == nil {
236236
// If the URL has no scheme, we treat it as a path (either absolute or relative to the base URL).
237237
switch packageKind {

Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -508,25 +508,38 @@ class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests {
508508
}
509509
}
510510

511-
func testFileURLsWithHostnames() throws {
511+
func testFileURLErrors() throws {
512512
enum ExpectedError {
513+
case invalidAbsolutePath
513514
case relativePath
514515
case unsupportedHostname
515516

516-
var manifestError: ManifestParseError {
517+
var manifestError: ManifestParseError? {
517518
switch self {
519+
case .invalidAbsolutePath:
520+
return nil
518521
case .relativePath:
519522
return .invalidManifestFormat("file:// URLs cannot be relative, did you mean to use '.package(path:)'?", diagnosticFile: nil)
520523
case .unsupportedHostname:
521524
return .invalidManifestFormat("file:// URLs with hostnames are not supported, are you missing a '/'?", diagnosticFile: nil)
522525
}
523526
}
527+
528+
var pathError: TSCBasic.PathValidationError? {
529+
switch self {
530+
case .invalidAbsolutePath:
531+
return .invalidAbsolutePath("")
532+
default:
533+
return nil
534+
}
535+
}
524536
}
525537

526538
let urls: [(String, ExpectedError)] = [
527539
("file://../best", .relativePath), // Possible attempt at a relative path.
528540
("file://somehost/bar", .unsupportedHostname), // Obviously non-local.
529541
("file://localhost/bar", .unsupportedHostname), // Local but non-trivial (e.g. on Windows, this is a UNC path).
542+
("file://", .invalidAbsolutePath) // Invalid path.
530543
]
531544
for (url, expectedError) in urls {
532545
let content = """
@@ -546,7 +559,14 @@ class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests {
546559

547560
let observability = ObservabilitySystem.makeForTesting()
548561
XCTAssertThrowsError(try loadAndValidateManifest(content, observabilityScope: observability.topScope), "expected error") { error in
549-
XCTAssertEqual(error as? ManifestParseError, expectedError.manifestError)
562+
switch error {
563+
case is ManifestParseError:
564+
XCTAssertEqual(error as? ManifestParseError, expectedError.manifestError)
565+
case is TSCBasic.PathValidationError:
566+
XCTAssertEqual(error.localizedDescription, expectedError.pathError?.localizedDescription)
567+
default:
568+
XCTFail("unhandled error type: \(error)")
569+
}
550570
}
551571
}
552572
}

0 commit comments

Comments
 (0)