cake-build / cake-build/cake

System.UnauthorizedAccessException when using Directory.GetDirectories(string filter, SearchScope scope) related APIs

Open
#3,056 1 comment 0 reactions 0 assignees View on GitHub
Improvement
Dominant language
C#
Stars
4.2k
Forks
778
Avg merge
1h 15m
Merged PRs (30d)
19

Description

### What You Are Seeing?
---> System.UnauthorizedAccessException: Access to the path '/path/without/read/permission' is denied.
---> System.IO.IOException: Permission denied

### What is Expected?
No exception should be thrown.

### What version of Cake are you using?
0.38.5

### Are you running on a 32 or 64 bit system?
64 bit

### What environment are you running on? Windows? Linux? Mac?
Linux

### Are you running on a CI Server? If so, which one?
Local dev machine

### How Did You Get This To Happen? (Steps to Reproduce)
```csharp
Task("Dummy")
.Does(() =>
{
// make sure ./tmp/ dir is not accesssable by $USER:$USER
GetFiles("./*", new GlobberSettings());
});
```

### Output Log
Error: System.AggregateException: One or more errors occurred. (Access to the path '/xxxx' is denied.)
---> System.UnauthorizedAccessException: Access to the path '/xxxx' is denied.
---> System.IO.IOException: Permission denied
--- End of inner exception stack trace ---
at System.IO.Enumeration.FileSystemEnumerator\`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
at System.IO.Enumeration.FileSystemEnumerator\`1.DequeueNextDirectory()
at System.IO.Enumeration.FileSystemEnumerator\`1.DirectoryFinished()
at System.IO.Enumeration.FileSystemEnumerator\`1.FindNextEntry(Byte* entryBufferPtr, Int32 bufferLength)
at System.IO.Enumeration.FileSystemEnumerator\`1.MoveNext()
at System.Collections.Generic.LargeArrayBuilder\`1.AddRange(IEnumerable\`1 items)
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable\`1 source)
at System.IO.DirectoryInfo.GetDirectories(String searchPattern, EnumerationOptions enumerationOptions)
at System.IO.DirectoryInfo.GetDirectories(String searchPattern, SearchOption searchOption)
at Cake.Core.IO.Directory.GetDirectories(String filter, SearchScope scope) in C:\projects\cake\src\Cake.Core\IO\Directory.cs:line 54
at Cake.Core.IO.Globbing.GlobVisitor.FindCandidates(DirectoryPath path, MatchableNode node, GlobVisitorContext context, SearchScope option, Boolean includeFiles, Boolean includeDirectories) in C:\projects\cake\src\Cake.Core\IO\Globbing\GlobVisitor.cs:line 227
at Cake.Core.IO.Globbing.GlobVisitor.VisitRecursiveWildcardSegment(RecursiveWildcardNode node, GlobVisitorContext context) in C:\projects\cake\src\Cake.Core\IO\Globbing\GlobVisitor.cs:line 37
at Cake.Core.IO.Globbing.Nodes.RecursiveWildcardNode.Accept(GlobVisitor globber, GlobVisitorContext context) in C:\projects\cake\src\Cake.Core\IO\Globbing\Nodes\RecursiveWildcardNode.cs:line 15
5
at Cake.Core.IO.Globbing.GlobVisitor.VisitSegment(PathNode node, GlobVisitorContext context) in C:\projects\cake\src\Cake.Core\IO\Globbing\GlobVisitor.cs:line 125
at Cake.Core.IO.Globbing.GlobVisitor.VisitUnixRoot(UnixRootNode node, GlobVisitorContext context) in C:\projects\cake\src\Cake.Core\IO\Globbing\GlobVisitor.cs:line 160
at Cake.Core.IO.Globbing.GlobVisitor.Walk(GlobNode node, GlobberSettings settings) in C:\projects\cake\src\Cake.Core\IO\Globbing\GlobVisitor.cs:line 25
at Cake.Core.IO.Globber.Match(String pattern, GlobberSettings settings) in C:\projects\cake\src\Cake.Core\IO\Globber.cs:line 80
at Cake.Common.IO.GlobbingAliases.GetFiles(ICakeContext context, String pattern, GlobberSettings settings) in C:\projects\cake\src\Cake.Common\IO\GlobbingAliases.cs:line 108
at Submission#0.GetFiles(String pattern, GlobberSettings settings) in :line 2384
...

The issue might because of this line:
https://github.com/cake-build/cake/blob/8bc15841e97944291946a89f335562244965247e/src/Cake.Core/IO/Directory.cs#L54

Stated in .NET api doc [here](https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.getdirectories?view=net-5.0#System_IO_DirectoryInfo_GetDirectories_System_String_System_IO_SearchOption_): this API call will thrown `UnauthorizedAccessException` if the caller does not have the required permission.

It would be great if we could have a chance to use this [API](https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.getdirectories?view=net-5.0#System_IO_DirectoryInfo_GetDirectories_System_String_System_IO_EnumerationOptions_):
```csharp
public System.IO.DirectoryInfo[] GetDirectories (string searchPattern, System.IO.EnumerationOptions enumerationOptions);
```
From what the doc says, one could set the property of the `System.IO.EnumerationOptions enumerationOptions` parameter:
```csharp
//Gets or sets a value that indicates whether to skip files or directories when access is denied (for example, UnauthorizedAccessException or SecurityException). The default is true.
public bool IgnoreInaccessible { get; set; }
```

Contributor guide

Open the contributing guide

Research direction

Start at src/Cake.Core/IO/Directory.cs line 54 and trace its callers through src/Cake.Core/IO/Globbing/GlobVisitor.cs line 227 and Cake.Common/IO/GlobbingAliases.cs line 108. Reproduce the Linux case with an inaccessible directory, compare the available DirectoryInfo overloads, and verify that GetFiles no longer throws for inaccessible paths while still returning accessible matches.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
build-system, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.