Skip to content

IFileSystemInfo.ResolveLinkTarget throws exception instead of returning null if the path is not a link #981

Closed

Description

@zivarah

Describe the bug
System.IO.FileSystemInfo.ResolveLinkTarget returns null when the directory is not a link.

IFileSystemInfo.ResolveLinkTarget ends up crashing with a null reference exception.

ResolveLinkTarget implementation in DirectoryInfoWrapper.cs

public override IFileSystemInfo ResolveLinkTarget(bool returnFinalTarget)
{
    return instance.ResolveLinkTarget(returnFinalTarget)
        .WrapFileSystemInfo(FileSystem);
}

WrapFileSystemInfo implementation in Converters.cs

private static FileSystemInfoBase WrapFileSystemInfo(IFileSystem fileSystem, FileSystemInfo item)
{
	if (item is FileInfo fileInfo)
	{
		return WrapFileInfo(fileSystem, fileInfo);
	}
	else if (item is DirectoryInfo directoryInfo)
	{
		return WrapDirectoryInfo(fileSystem, directoryInfo);
	}
	else
	{
		throw new NotImplementedException(string.Format(
			CultureInfo.InvariantCulture,
			"The type {0} is not recognized by the System.IO.Abstractions library.",
			item.GetType().AssemblyQualifiedName
		));
	}
}

The null reference we end up hitting is because item is null in WrapFileSystemInfo.

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=System.Private.CoreLib
  StackTrace:
   at System.Object.GetType()
   at System.IO.Abstractions.Converters.WrapFileSystemInfo(IFileSystem fileSystem, FileSystemInfo item) in /home/runner/work/System.IO.Abstractions/System.IO.Abstractions/src/TestableIO.System.IO.Abstractions.Wrappers/Converters.cs:line 42

To Reproduce

IFileSystem fs = new FileSystem();
IDirectoryInfo dirinfo = fs.Directory.CreateDirectory(@"C:\Some\Dir");
IFileSystemInfo? target = dirinfo.ResolveLinkTarget(true); //Crash

Expected behavior
ResolveLinkTarget should propagate the null return of the underlying System.IO API one way or another.
That API could do it directly, though it seems like WrapFileSystemInfo really ought to do the propagation itself.

Fix option 1:

private static FileSystemInfoBase WrapFileSystemInfo(IFileSystem fileSystem, FileSystemInfo item)
{
	if (item == null)
	{
		return null;
	}
	...
}

Fix option 2:

public override IFileSystemInfo ResolveLinkTarget(bool returnFinalTarget)
{
    return instance.ResolveLinkTarget(returnFinalTarget)
        ?.WrapFileSystemInfo(FileSystem);
}

Activity

  1. zivarah commented on May 3, 2023

    @zivarah
    ContributorAuthor

    I would be happy to submit a fix for this, but would like some input from the project team first. Was it an intentional decision to not propagate nulls in WrapFileSystemInfo?

  2. fgreinacher commented on May 4, 2023

    @fgreinacher
    Contributor

    Wow, thanks for the detailed report, this is really appreciated!

    I would be happy to submit a fix for this, but would like some input from the project team first. Was it an intentional decision to not propagate nulls in WrapFileSystemInfo?

    No, it is a bug. All the Wrap* methods should pass on null values. Feel free to submit a PR 🙇

  3. added
    state: ready to pickIssues that are ready for being worked on
    area: coreIssues that address the core abstractions & the wrappers
    and removed on May 4, 2023
  4. added 2 commits that reference this issue on May 4, 2023
    3801795
    c6c2907
  5. added a commit that references this issue on May 4, 2023
    04abe02
  6. github-actions commented on May 12, 2023

    @github-actions

    This is addressed in release v19.2.22.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues that address the core abstractions & the wrappersstate: ready to pickIssues that are ready for being worked onstate: releasedIssues that are releasedtype: bugIssues that describe misbehaving functionality

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions