Skip to content

Catch UnauthorizedAccessException in file path enumeration #480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 1, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 56 additions & 21 deletions src/PowerShellEditorServices/Workspace/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,20 @@ public ScriptFile GetFile(string filePath)
{
Validate.IsNotNullOrEmptyString("filePath", filePath);

// Resolve the full file path
// Resolve the full file path
string resolvedFilePath = this.ResolveFilePath(filePath);
string keyName = resolvedFilePath.ToLower();

// Make sure the file isn't already loaded into the workspace
ScriptFile scriptFile = null;
if (!this.workspaceFiles.TryGetValue(keyName, out scriptFile))
{
// This method allows FileNotFoundException to bubble up
// This method allows FileNotFoundException to bubble up
// if the file isn't found.
using (FileStream fileStream = new FileStream(resolvedFilePath, FileMode.Open, FileAccess.Read))
using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
scriptFile =
scriptFile =
new ScriptFile(
resolvedFilePath,
filePath,
Expand Down Expand Up @@ -115,15 +115,15 @@ public ScriptFile GetFileBuffer(string filePath, string initialBuffer)
{
Validate.IsNotNullOrEmptyString("filePath", filePath);

// Resolve the full file path
// Resolve the full file path
string resolvedFilePath = this.ResolveFilePath(filePath);
string keyName = resolvedFilePath.ToLower();

// Make sure the file isn't already loaded into the workspace
ScriptFile scriptFile = null;
if (!this.workspaceFiles.TryGetValue(keyName, out scriptFile) && initialBuffer != null)
{
scriptFile =
scriptFile =
new ScriptFile(
resolvedFilePath,
filePath,
Expand Down Expand Up @@ -159,19 +159,19 @@ public void CloseFile(ScriptFile scriptFile)
}

/// <summary>
/// Gets all file references by recursively searching
/// Gets all file references by recursively searching
/// through referenced files in a scriptfile
/// </summary>
/// <param name="scriptFile">Contains the details and contents of an open script file</param>
/// <returns>A scriptfile array where the first file
/// <returns>A scriptfile array where the first file
/// in the array is the "root file" of the search</returns>
public ScriptFile[] ExpandScriptReferences(ScriptFile scriptFile)
{
Dictionary<string, ScriptFile> referencedScriptFiles = new Dictionary<string, ScriptFile>();
List<ScriptFile> expandedReferences = new List<ScriptFile>();

// add original file so it's not searched for, then find all file references
referencedScriptFiles.Add(scriptFile.Id, scriptFile);
referencedScriptFiles.Add(scriptFile.Id, scriptFile);
RecursivelyFindReferences(scriptFile, referencedScriptFiles);

// remove original file from referened file and add it as the first element of the
Expand Down Expand Up @@ -219,25 +219,60 @@ public string GetRelativePath(string filePath)
/// <returns>An enumerator over the PowerShell files found in the workspace</returns>
public IEnumerable<string> EnumeratePSFiles()
{
if (WorkspacePath == null
|| !Directory.Exists(WorkspacePath))
if (WorkspacePath == null || !Directory.Exists(WorkspacePath))
{
yield break;
return Enumerable.Empty<string>();
}

return this.RecursivelyEnumerateFiles(WorkspacePath);
}

#endregion

#region Private Methods

private IEnumerable<string> RecursivelyEnumerateFiles(string folderPath)
{
var foundFiles = Enumerable.Empty<string>();
var patterns = new string[] { @"*.ps1", @"*.psm1", @"*.psd1" };
foreach(var pattern in patterns)

try
{
foreach (var file in Directory.EnumerateFiles(WorkspacePath, pattern, SearchOption.AllDirectories))
IEnumerable<string> subDirs = Directory.EnumerateDirectories(folderPath);
foreach (string dir in subDirs)
{
yield return file;
foundFiles =
foundFiles.Concat(
RecursivelyEnumerateFiles(dir));
}
}
}
catch (UnauthorizedAccessException e)
{
Logger.WriteException(
$"Could not enumerate files in the path '{folderPath}' due to the path not being accessible",
e);
}

#endregion
foreach (var pattern in patterns)
{
try
{
foundFiles =
foundFiles.Concat(
Directory.EnumerateFiles(
folderPath,
pattern));
}
catch (UnauthorizedAccessException e)
{
Logger.WriteException(
$"Could not enumerate files in the path '{folderPath}' due to a file not being accessible",
e);
}
}

#region Private Methods
return foundFiles;
}

/// <summary>
/// Recusrively searches through referencedFiles in scriptFiles
Expand All @@ -246,11 +281,11 @@ public IEnumerable<string> EnumeratePSFiles()
/// <param name="scriptFile">Details an contents of "root" script file</param>
/// <param name="referencedScriptFiles">A Dictionary of referenced script files</param>
private void RecursivelyFindReferences(
ScriptFile scriptFile,
ScriptFile scriptFile,
Dictionary<string, ScriptFile> referencedScriptFiles)
{
// Get the base path of the current script for use in resolving relative paths
string baseFilePath =
string baseFilePath =
GetBaseFilePath(
scriptFile.FilePath);

Expand Down Expand Up @@ -347,12 +382,12 @@ private string GetBaseFilePath(string filePath)
// TODO: Assert instead?
throw new InvalidOperationException(
string.Format(
"Must provide a full path for originalScriptPath: {0}",
"Must provide a full path for originalScriptPath: {0}",
filePath));
}

// Get the directory of the file path
return Path.GetDirectoryName(filePath);
return Path.GetDirectoryName(filePath);
}

private string ResolveRelativeScriptPath(string baseFilePath, string relativePath)
Expand Down