From 5e9f275d7c04a02302c5d8e309ed83c98695304d Mon Sep 17 00:00:00 2001 From: Antony Male Date: Wed, 13 Jan 2016 09:51:42 +0000 Subject: [PATCH] Limit recursion when searching for conflict files Fixes #195 --- .../Services/Conflicts/ConflictFileManager.cs | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/SyncTrayzor/Services/Conflicts/ConflictFileManager.cs b/src/SyncTrayzor/Services/Conflicts/ConflictFileManager.cs index 97b6b3ad..dd1cb639 100644 --- a/src/SyncTrayzor/Services/Conflicts/ConflictFileManager.cs +++ b/src/SyncTrayzor/Services/Conflicts/ConflictFileManager.cs @@ -89,6 +89,7 @@ public class ConflictFileManager : IConflictFileManager private static readonly Regex conflictRegex = new Regex(@"^(?.*).sync-conflict-(?\d{4})(?\d{2})(?\d{2})-(?\d{2})(?\d{2})(?\d{2})(?.*)(?\..*)$"); private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + private const int maxSearchDepth = 255; // Loosely based on the max path length (a bit over) private readonly IFilesystemProvider filesystemProvider; @@ -128,14 +129,15 @@ private void FindConflictsImpl(string basePath, SlimObservable subj logger.Debug("Looking for conflicts in {0}", basePath); var conflictLookup = new Dictionary>(); - var stack = new Stack(); - stack.Push(basePath); + var stack = new Stack(); + stack.Push(new SearchDirectory(basePath, 0)); while (stack.Count > 0) { cancellationToken.ThrowIfCancellationRequested(); conflictLookup.Clear(); - var directory = stack.Pop(); + var searchDirectory = stack.Pop(); + var directory = searchDirectory.Directory; foreach (var fileName in this.TryGetFiles(directory, conflictPattern, System.IO.SearchOption.TopDirectoryOnly)) { @@ -164,14 +166,21 @@ private void FindConflictsImpl(string basePath, SlimObservable subj subject.Next(new ConflictSet(file, conflicts)); } - foreach (var subDirectory in this.TryGetDirectories(directory, "*", System.IO.SearchOption.TopDirectoryOnly)) + if (searchDirectory.Depth < maxSearchDepth) { - if (subDirectory == stVersionsFolder) - continue; + foreach (var subDirectory in this.TryGetDirectories(directory, "*", System.IO.SearchOption.TopDirectoryOnly)) + { + if (subDirectory == stVersionsFolder) + continue; - stack.Push(Path.Combine(directory, subDirectory)); + stack.Push(new SearchDirectory(Path.Combine(directory, subDirectory), searchDirectory.Depth + 1)); - cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + else + { + logger.Warn($"Max search depth of {maxSearchDepth} exceeded with path {directory}. Not proceeding further."); } } } @@ -311,5 +320,17 @@ public void ResolveConflict(ConflictSet conflictSet, string chosenFilePath) this.filesystemProvider.MoveFile(chosenFilePath, conflictSet.File.FilePath); } } + + private struct SearchDirectory + { + public readonly string Directory; + public readonly int Depth; + + public SearchDirectory(string directory, int depth) + { + this.Directory = directory; + this.Depth = depth; + } + } } }