@@ -292,7 +292,9 @@ public IEnumerable<string> EnumeratePSFiles()
292292 return Enumerable . Empty < string > ( ) ;
293293 }
294294
295- return this . RecursivelyEnumerateFiles ( WorkspacePath ) ;
295+ var foundFiles = new List < string > ( ) ;
296+ this . RecursivelyEnumerateFiles ( WorkspacePath , ref foundFiles ) ;
297+ return foundFiles ;
296298 }
297299
298300 #endregion
@@ -301,109 +303,95 @@ public IEnumerable<string> EnumeratePSFiles()
301303
302304 /// <summary>
303305 /// Find PowerShell files recursively down from a given directory path.
304- /// Currently returns files in depth-first order.
306+ /// Currently collects files in depth-first order.
305307 /// Directory.GetFiles(folderPath, pattern, SearchOption.AllDirectories) would provide this,
306308 /// but a cycle in the filesystem will cause that to enter an infinite loop.
307309 /// </summary>
308- /// <param name="folderPath">The absolute path of the base folder to search.</param>
309- /// <returns>
310- /// All PowerShell files in the recursive directory hierarchy under the given base directory, up to 64 directories deep.
311- /// </returns>
312- private IEnumerable < string > RecursivelyEnumerateFiles ( string folderPath )
310+ /// <param name="folderPath">The path of the current directory to find files in</param>
311+ /// <param name="foundFiles">The accumulator for files found so far.</param>
312+ /// <param name="currDepth">The current depth of the recursion from the original base directory.</param>
313+ private void RecursivelyEnumerateFiles ( string folderPath , ref List < string > foundFiles , int currDepth = 0 )
313314 {
314- var foundFiles = new List < string > ( ) ;
315- var dirStack = new Stack < string > ( ) ;
316-
317- // Kick the search off with the base directory
318- dirStack . Push ( folderPath ) ;
319-
320315 const int recursionDepthLimit = 64 ;
321- while ( dirStack . Any ( ) )
322- {
323- string currDir = dirStack . Pop ( ) ;
324-
325- // Look for any PowerShell files in the current directory
326- foreach ( string pattern in s_psFilePatterns )
327- {
328- string [ ] psFiles ;
329- try
330- {
331- psFiles = Directory . GetFiles ( currDir , pattern , SearchOption . TopDirectoryOnly ) ;
332- }
333- catch ( DirectoryNotFoundException e )
334- {
335- this . logger . WriteHandledException (
336- $ "Could not enumerate files in the path '{ currDir } ' due to it being an invalid path",
337- e ) ;
338-
339- continue ;
340- }
341- catch ( PathTooLongException e )
342- {
343- this . logger . WriteHandledException (
344- $ "Could not enumerate files in the path '{ currDir } ' due to the path being too long",
345- e ) ;
346-
347- continue ;
348- }
349- catch ( Exception e ) when ( e is SecurityException || e is UnauthorizedAccessException )
350- {
351- this . logger . WriteHandledException (
352- $ "Could not enumerate files in the path '{ currDir } ' due to the path not being accessible",
353- e ) ;
354-
355- continue ;
356- }
357-
358- foundFiles . AddRange ( psFiles ) ;
359- }
360-
361- // Prevent unbounded recursion here
362- // If we get too deep, keep processing but go no deeper
363- if ( dirStack . Count >= recursionDepthLimit )
364- {
365- this . logger . Write ( LogLevel . Warning , $ "Recursion depth limit hit for path { folderPath } ") ;
366- continue ;
367- }
368316
369- // Add the recursive directories to search next
370- string [ ] subDirs ;
317+ // Look for any PowerShell files in the current directory
318+ foreach ( string pattern in s_psFilePatterns )
319+ {
320+ string [ ] psFiles ;
371321 try
372322 {
373- subDirs = Directory . GetDirectories ( currDir ) ;
323+ psFiles = Directory . GetFiles ( folderPath , pattern , SearchOption . TopDirectoryOnly ) ;
374324 }
375325 catch ( DirectoryNotFoundException e )
376326 {
377327 this . logger . WriteHandledException (
378- $ "Could not enumerate directories in the path '{ currDir } ' due to it being an invalid path",
328+ $ "Could not enumerate files in the path '{ folderPath } ' due to it being an invalid path",
379329 e ) ;
380330
381331 continue ;
382332 }
383333 catch ( PathTooLongException e )
384334 {
385335 this . logger . WriteHandledException (
386- $ "Could not enumerate directories in the path '{ currDir } ' due to the path being too long",
336+ $ "Could not enumerate files in the path '{ folderPath } ' due to the path being too long",
387337 e ) ;
388338
389339 continue ;
390340 }
391341 catch ( Exception e ) when ( e is SecurityException || e is UnauthorizedAccessException )
392342 {
393343 this . logger . WriteHandledException (
394- $ "Could not enumerate directories in the path '{ currDir } ' due to the path not being accessible",
344+ $ "Could not enumerate files in the path '{ folderPath } ' due to the path not being accessible",
395345 e ) ;
396346
397347 continue ;
398348 }
399349
400- foreach ( string subDir in subDirs )
401- {
402- dirStack . Push ( subDir ) ;
403- }
350+ foundFiles . AddRange ( psFiles ) ;
404351 }
405352
406- return foundFiles ;
353+ // Prevent unbounded recursion here
354+ if ( currDepth >= recursionDepthLimit )
355+ {
356+ this . logger . Write ( LogLevel . Warning , $ "Recursion depth limit hit for path { folderPath } ") ;
357+ return ;
358+ }
359+
360+ // Add the recursive directories to search next
361+ string [ ] subDirs ;
362+ try
363+ {
364+ subDirs = Directory . GetDirectories ( folderPath ) ;
365+ }
366+ catch ( DirectoryNotFoundException e )
367+ {
368+ this . logger . WriteHandledException (
369+ $ "Could not enumerate directories in the path '{ folderPath } ' due to it being an invalid path",
370+ e ) ;
371+
372+ return ;
373+ }
374+ catch ( PathTooLongException e )
375+ {
376+ this . logger . WriteHandledException (
377+ $ "Could not enumerate directories in the path '{ folderPath } ' due to the path being too long",
378+ e ) ;
379+
380+ return ;
381+ }
382+ catch ( Exception e ) when ( e is SecurityException || e is UnauthorizedAccessException )
383+ {
384+ this . logger . WriteHandledException (
385+ $ "Could not enumerate directories in the path '{ folderPath } ' due to the path not being accessible",
386+ e ) ;
387+
388+ return ;
389+ }
390+
391+ foreach ( string subDir in subDirs )
392+ {
393+ RecursivelyEnumerateFiles ( subDir , ref foundFiles , currDepth : currDepth + 1 ) ;
394+ }
407395 }
408396
409397 /// <summary>
0 commit comments