Skip to content
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

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

Open
junjiequ opened this issue Jan 27, 2021 · 1 comment

Comments

@junjiequ
Copy link

junjiequ commented Jan 27, 2021

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)

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:

return _directory.GetDirectories(filter, option)

Stated in .NET api doc here: 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:

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:

//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; }
@augustoproiete augustoproiete added this to the v1.x Next milestone Jan 28, 2021
@augustoproiete
Copy link
Member

Seem like a good addition to the GetDirectories & GetFiles aliases. 👍

In the meantime, a possible workaround (though without the globbing support) would be to use System.IO.Directory.EnumerateFiles and convert to Cake's FilePath for use within the build script.

e.g.

Task("Dummy")
    .Does(() =>
{
    // make sure ./tmp/ dir is not accesssable by $USER:$USER
    var files = System.IO.Directory.EnumerateFiles(@"./", "*", new EnumerationOptions
    {
        IgnoreInaccessible = true,
    }).Select(f => new FilePath(f));
 
    // ...
});

RunTarget("Dummy");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants