Chromium Code Reviews

Unified Diff: sdk/lib/_internal/pub/lib/src/io.dart

Issue 14586004: Fix listing directories with recursive symlinks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
« no previous file with comments | « no previous file | sdk/lib/_internal/pub/pub.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/pub/lib/src/io.dart
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 1620837c2b2f3362997abbf78ac581a52b543dab..0c45b33ad02cf552107e13dd3750647950d621a9 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -133,16 +133,9 @@ String createTempDir([dir = '']) {
/// The returned paths are guaranteed to begin with [dir].
List<String> listDir(String dir, {bool recursive: false,
bool includeHidden: false}) {
- List<String> doList(String dir, Set<String> listedDirectories) {
+ Set<String> visited = new Set<String>();
+ List<String> doList(String dir) {
var contents = <String>[];
-
- // Avoid recursive symlinks.
- var resolvedPath = new File(dir).fullPathSync();
- if (listedDirectories.contains(resolvedPath)) return [];
-
- listedDirectories = new Set<String>.from(listedDirectories);
- listedDirectories.add(resolvedPath);
-
log.io("Listing directory $dir.");
var children = <String>[];
Andrei Mouravski 2013/05/02 00:16:13 Why not reuse contents instead of making children?
Bob Nystrom 2013/05/02 00:18:59 I'm not exactly sure, but I believe the existed co
@@ -151,14 +144,23 @@ List<String> listDir(String dir, {bool recursive: false,
continue;
}
+ // Filter out duplicate entries caused by recursive symlinks. We check
+ // for duplicate entities instead of looking for the symlink cycle itself
+ // because [identicalSync] does not consider a link identical to its
+ // target. That means a directory and the recursive symlink to it will
+ // show up as different entities.
+ if (visited.any((previous) =>
+ FileSystemEntity.identicalSync(previous, entity.path))) {
+ continue;
+ }
+ visited.add(entity.path);
+
contents.add(entity.path);
if (entity is Directory) {
// TODO(nweiz): don't manually recurse once issue 4794 is fixed.
// Note that once we remove the manual recursion, we'll need to
// explicitly filter out files in hidden directories.
- if (recursive) {
- children.addAll(doList(entity.path, listedDirectories));
- }
+ if (recursive) children.addAll(doList(entity.path));
}
}
@@ -167,7 +169,7 @@ List<String> listDir(String dir, {bool recursive: false,
return contents;
}
- return doList(dir, new Set<String>());
+ return doList(dir);
}
/// Returns whether [dir] exists on the file system. This will return `true` for
« no previous file with comments | « no previous file | sdk/lib/_internal/pub/pub.status » ('j') | no next file with comments »

Powered by Google App Engine