From c57e8634227edea4c725fe0e152dbcba837e0945 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Thu, 29 Nov 2018 15:44:12 -0800 Subject: [PATCH 1/4] [Ignore] Fix recursion count bug --- .../Workspace/Workspace.cs | 122 ++++++++---------- 1 file changed, 56 insertions(+), 66 deletions(-) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index 7dc328b41..07b32fef5 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -292,7 +292,9 @@ public IEnumerable EnumeratePSFiles() return Enumerable.Empty(); } - return this.RecursivelyEnumerateFiles(WorkspacePath); + var foundFiles = new List(); + this.RecursivelyEnumerateFiles(WorkspacePath, ref foundFiles); + return foundFiles; } #endregion @@ -309,73 +311,22 @@ public IEnumerable EnumeratePSFiles() /// /// All PowerShell files in the recursive directory hierarchy under the given base directory, up to 64 directories deep. /// - private IEnumerable RecursivelyEnumerateFiles(string folderPath) + private void RecursivelyEnumerateFiles(string folderPath, ref List foundFiles, int currDepth = 0) { - var foundFiles = new List(); - var dirStack = new Stack(); - - // Kick the search off with the base directory - dirStack.Push(folderPath); - const int recursionDepthLimit = 64; - while (dirStack.Any()) - { - string currDir = dirStack.Pop(); - - // Look for any PowerShell files in the current directory - foreach (string pattern in s_psFilePatterns) - { - string[] psFiles; - try - { - psFiles = Directory.GetFiles(currDir, pattern, SearchOption.TopDirectoryOnly); - } - catch (DirectoryNotFoundException e) - { - this.logger.WriteHandledException( - $"Could not enumerate files in the path '{currDir}' due to it being an invalid path", - e); - - continue; - } - catch (PathTooLongException e) - { - this.logger.WriteHandledException( - $"Could not enumerate files in the path '{currDir}' due to the path being too long", - e); - - continue; - } - catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) - { - this.logger.WriteHandledException( - $"Could not enumerate files in the path '{currDir}' due to the path not being accessible", - e); - - continue; - } - - foundFiles.AddRange(psFiles); - } - - // Prevent unbounded recursion here - // If we get too deep, keep processing but go no deeper - if (dirStack.Count >= recursionDepthLimit) - { - this.logger.Write(LogLevel.Warning, $"Recursion depth limit hit for path {folderPath}"); - continue; - } - // Add the recursive directories to search next - string[] subDirs; + // Look for any PowerShell files in the current directory + foreach (string pattern in s_psFilePatterns) + { + string[] psFiles; try { - subDirs = Directory.GetDirectories(currDir); + psFiles = Directory.GetFiles(folderPath, pattern, SearchOption.TopDirectoryOnly); } catch (DirectoryNotFoundException e) { this.logger.WriteHandledException( - $"Could not enumerate directories in the path '{currDir}' due to it being an invalid path", + $"Could not enumerate files in the path '{folderPath}' due to it being an invalid path", e); continue; @@ -383,7 +334,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) catch (PathTooLongException e) { this.logger.WriteHandledException( - $"Could not enumerate directories in the path '{currDir}' due to the path being too long", + $"Could not enumerate files in the path '{folderPath}' due to the path being too long", e); continue; @@ -391,19 +342,58 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) { this.logger.WriteHandledException( - $"Could not enumerate directories in the path '{currDir}' due to the path not being accessible", + $"Could not enumerate files in the path '{folderPath}' due to the path not being accessible", e); continue; } - foreach (string subDir in subDirs) - { - dirStack.Push(subDir); - } + foundFiles.AddRange(psFiles); } - return foundFiles; + // Prevent unbounded recursion here + // If we get too deep, keep processing but go no deeper + if (currDepth >= recursionDepthLimit) + { + this.logger.Write(LogLevel.Warning, $"Recursion depth limit hit for path {folderPath}"); + return; + } + + // Add the recursive directories to search next + string[] subDirs; + try + { + subDirs = Directory.GetDirectories(folderPath); + } + catch (DirectoryNotFoundException e) + { + this.logger.WriteHandledException( + $"Could not enumerate directories in the path '{folderPath}' due to it being an invalid path", + e); + + return; + } + catch (PathTooLongException e) + { + this.logger.WriteHandledException( + $"Could not enumerate directories in the path '{folderPath}' due to the path being too long", + e); + + return; + } + catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) + { + this.logger.WriteHandledException( + $"Could not enumerate directories in the path '{folderPath}' due to the path not being accessible", + e); + + return; + } + + foreach (string subDir in subDirs) + { + RecursivelyEnumerateFiles(subDir, ref foundFiles, currDepth + 1); + } } /// From 7c36317f86c493680d178532b73a289bbdf62912 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Thu, 29 Nov 2018 15:57:08 -0800 Subject: [PATCH 2/4] [Ignore] Fix up XML comments --- src/PowerShellEditorServices/Workspace/Workspace.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index 07b32fef5..770da4e04 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -303,14 +303,13 @@ public IEnumerable EnumeratePSFiles() /// /// Find PowerShell files recursively down from a given directory path. - /// Currently returns files in depth-first order. + /// Currently collects files in depth-first order. /// Directory.GetFiles(folderPath, pattern, SearchOption.AllDirectories) would provide this, /// but a cycle in the filesystem will cause that to enter an infinite loop. /// - /// The absolute path of the base folder to search. - /// - /// All PowerShell files in the recursive directory hierarchy under the given base directory, up to 64 directories deep. - /// + /// The path of the current directory to find files in + /// The accumulator for files found so far. + /// The current depth of the recursion from the original base directory. private void RecursivelyEnumerateFiles(string folderPath, ref List foundFiles, int currDepth = 0) { const int recursionDepthLimit = 64; From e4d34166f74ca59570d5efe4c02f2261cd3ba8b1 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Thu, 29 Nov 2018 15:59:17 -0800 Subject: [PATCH 3/4] [Ignore] Improve comment --- src/PowerShellEditorServices/Workspace/Workspace.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index 770da4e04..ab60c5681 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -351,7 +351,6 @@ private void RecursivelyEnumerateFiles(string folderPath, ref List found } // Prevent unbounded recursion here - // If we get too deep, keep processing but go no deeper if (currDepth >= recursionDepthLimit) { this.logger.Write(LogLevel.Warning, $"Recursion depth limit hit for path {folderPath}"); From ae2a77c511400dce500a1a5d887faf728e3ee384 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Thu, 29 Nov 2018 21:57:11 -0800 Subject: [PATCH 4/4] Add label to currDepth parameter --- src/PowerShellEditorServices/Workspace/Workspace.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index ab60c5681..b53832f07 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -390,7 +390,7 @@ private void RecursivelyEnumerateFiles(string folderPath, ref List found foreach (string subDir in subDirs) { - RecursivelyEnumerateFiles(subDir, ref foundFiles, currDepth + 1); + RecursivelyEnumerateFiles(subDir, ref foundFiles, currDepth: currDepth + 1); } }