Skip to content

Commit 257fe0a

Browse files
committed
Fix rmtree failing if there are symlinks to dirs
1 parent 38b749b commit 257fe0a

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed

Sources/sys/Path.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,26 +194,28 @@ extension String {
194194
return hasPrefix("/")
195195
}
196196

197-
/// - Returns: true if the string is a directory on the filesystem
197+
/**
198+
- Returns: true if the string is a directory on the filesystem
199+
- Note: symlinks are NOT resolved
200+
*/
198201
public var isDirectory: Bool {
199202
var mystat = stat()
200-
let rv = stat(self, &mystat)
203+
let rv = lstat(self, &mystat)
201204
return rv == 0 && (mystat.st_mode & S_IFMT) == S_IFDIR
202205
}
203206

204207
/**
205208
- Returns: true if the string is a file on the filesystem
206-
- Note: symlinks are resolved
209+
- Note: symlinks are NOT resolved
207210
*/
208211
public var isFile: Bool {
209212
var mystat = stat()
210-
let rv = stat(self, &mystat)
213+
let rv = lstat(self, &mystat)
211214
return rv == 0 && (mystat.st_mode & S_IFMT) == S_IFREG
212215
}
213216

214217
/**
215218
- Returns: true if the string is a symlink on the filesystem
216-
- Note: symlinks are resolved
217219
*/
218220
public var isSymlink: Bool {
219221
var mystat = stat()

Support/swiftpm.xcodeproj/project.pbxproj

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
63353A611BB4C4CD00D6C4B0 /* ShellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63353A5D1BB4C4CD00D6C4B0 /* ShellTests.swift */; };
1515
63353A621BB4C4CD00D6C4B0 /* StringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63353A5E1BB4C4CD00D6C4B0 /* StringTests.swift */; };
1616
635C147D1BCDA0A900D4C4A9 /* TargetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635C147C1BCDA0A900D4C4A9 /* TargetTests.swift */; };
17+
636EF11A1C0D0F1E00626610 /* MiscTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636EF1191C0D0F1E00626610 /* MiscTests.swift */; };
1718
637E98DA1BD95D0A0044B53E /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637E98D91BD95D0A0044B53E /* Utilities.swift */; };
1819
63ACA7EC1BED42160095510D /* PackageDescriptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63ACA7EB1BED42160095510D /* PackageDescriptionTests.swift */; };
1920
63D2BC181BFD6287006E395C /* PackageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63D2BC171BFD6287006E395C /* PackageTests.swift */; };
@@ -187,6 +188,7 @@
187188
63353A5E1BB4C4CD00D6C4B0 /* StringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StringTests.swift; path = ../Tests/sys/StringTests.swift; sourceTree = "<group>"; };
188189
63353AA61BB5DCF400D6C4B0 /* .. */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ..; sourceTree = "<group>"; };
189190
635C147C1BCDA0A900D4C4A9 /* TargetTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TargetTests.swift; path = ../Tests/dep/TargetTests.swift; sourceTree = "<group>"; };
191+
636EF1191C0D0F1E00626610 /* MiscTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MiscTests.swift; path = ../Tests/sys/MiscTests.swift; sourceTree = "<group>"; };
190192
637E98D91BD95D0A0044B53E /* Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Utilities.swift; path = ../Tests/dep/Utilities.swift; sourceTree = "<group>"; };
191193
63ACA7EB1BED42160095510D /* PackageDescriptionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PackageDescriptionTests.swift; path = ../Tests/PackageDescription/PackageDescriptionTests.swift; sourceTree = "<group>"; };
192194
63D2BC171BFD6287006E395C /* PackageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PackageTests.swift; path = ../Tests/dep/PackageTests.swift; sourceTree = "<group>"; };
@@ -297,11 +299,12 @@
297299
63CF91C21BE9419100265702 /* sys */ = {
298300
isa = PBXGroup;
299301
children = (
300-
E1E286D51BD83BE40015F0C5 /* ResourcesTests.swift */,
302+
636EF1191C0D0F1E00626610 /* MiscTests.swift */,
301303
63353A5C1BB4C4CD00D6C4B0 /* PathTests.swift */,
302-
E136D9411BD5F35D000DFCE6 /* TOMLTests.swift */,
303-
63353A5E1BB4C4CD00D6C4B0 /* StringTests.swift */,
304+
E1E286D51BD83BE40015F0C5 /* ResourcesTests.swift */,
304305
63353A5D1BB4C4CD00D6C4B0 /* ShellTests.swift */,
306+
63353A5E1BB4C4CD00D6C4B0 /* StringTests.swift */,
307+
E136D9411BD5F35D000DFCE6 /* TOMLTests.swift */,
305308
);
306309
name = sys;
307310
sourceTree = "<group>";
@@ -592,6 +595,7 @@
592595
63353A611BB4C4CD00D6C4B0 /* ShellTests.swift in Sources */,
593596
E1E286D61BD83BE40015F0C5 /* ResourcesTests.swift in Sources */,
594597
63DC25371BF413BF00EDCFBF /* XCTestCaseProvider.swift in Sources */,
598+
636EF11A1C0D0F1E00626610 /* MiscTests.swift in Sources */,
595599
63353A621BB4C4CD00D6C4B0 /* StringTests.swift in Sources */,
596600
);
597601
runOnlyForDeploymentPostprocessing = 0;

Tests/sys/MiscTests.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2015 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import sys
12+
import POSIX
13+
import XCTest
14+
import libc
15+
16+
class RmtreeTests: XCTestCase {
17+
18+
func testDoesNotFollowSymlinks() {
19+
do {
20+
try mkdtemp("foo") { root in
21+
let root = try realpath(root)
22+
23+
try mkdir(root, "foo")
24+
try mkdir(root, "bar")
25+
try mkdir(root, "bar/baz")
26+
try mkdir(root, "bar/baz/goo")
27+
try symlink(create: "\(root)/foo/symlink", pointingAt: "\(root)/bar", relativeTo: root)
28+
29+
XCTAssertTrue("\(root)/foo/symlink".isSymlink)
30+
XCTAssertEqual(try! realpath("\(root)/foo/symlink"), "\(root)/bar")
31+
XCTAssertTrue(try! realpath("\(root)/foo/symlink/baz").isDirectory)
32+
33+
try rmtree(root, "foo")
34+
35+
XCTAssertFalse("\(root)/foo".exists)
36+
XCTAssertFalse("\(root)/foo".isDirectory)
37+
XCTAssertTrue("\(root)/bar/baz".isDirectory)
38+
XCTAssertTrue("\(root)/bar/baz/goo".isDirectory)
39+
}
40+
} catch {
41+
XCTFail("\(error)")
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)