Skip to content

Commit

Permalink
fix: handling of whitespace-only filenames (#439)
Browse files Browse the repository at this point in the history
As reported in
TestableIO/System.IO.Abstractions#1070,
whitespace-only files are treated differently depending on the
underlying operating system:
- Windows only supports unicode-whitespace, but throws on filenames with
only blanks
- Linux supports both files with only blanks or with unicode-whitespace
  • Loading branch information
vbreuss committed Dec 31, 2023
1 parent 642b210 commit e8e1ef7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
Expand Up @@ -33,7 +33,7 @@ public IFileInfo New(string fileName)
throw new ArgumentNullException(nameof(fileName));
}

if (fileName.Trim() == "" && Execute.IsWindows)
if (fileName.IsEffectivelyEmpty())
{
throw ExceptionFactory.PathIsEmpty("path");
}
Expand Down
30 changes: 30 additions & 0 deletions Source/Testably.Abstractions.Testing/Helpers/PathHelper.cs
Expand Up @@ -32,6 +32,36 @@ internal static bool HasIllegalCharacters(this string path, IFileSystem fileSyst
() => false);
}

/// <summary>
/// Returns true if the path is effectively empty for the current OS.
/// For unix, this is empty or null. For Windows, this is empty, null, or
/// just spaces ((char)32).
/// </summary>
internal static bool IsEffectivelyEmpty(this string path)
{
if (string.IsNullOrEmpty(path))
{
return true;
}

return Execute.OnWindows(
() => Execute.OnNetFramework(
() => string.IsNullOrWhiteSpace(path),
() =>
{
foreach (char c in path)
{
if (c != ' ')
{
return false;
}
}
return true;
}),
() => false);
}

internal static bool IsUncPath([NotNullWhen(true)] this string? path)
{
if (path == null)
Expand Down
Expand Up @@ -70,6 +70,42 @@ public void New_ShouldSetLength(string path, byte[] bytes)
result.Should().Be(bytes.Length);
}

[SkippableFact]
public void New_WithUnicodeWhitespace_ShouldNotThrow()
{
var exception = Record.Exception(() =>
{
FileSystem.FileInfo.New("\u00A0"); // Unicode char that's treated as whitespace
});

if (Test.IsNetFramework)
{
exception.Should().BeOfType<ArgumentException>();
}
else
{
exception.Should().BeNull();
}
}

[SkippableFact]
public void New_WithWhitespace_ShouldThrowOnlyOnWindows()
{
var exception = Record.Exception(() =>
{
FileSystem.FileInfo.New(" ");
});

if (Test.RunsOnWindows)
{
exception.Should().BeOfType<ArgumentException>();
}
else
{
exception.Should().BeNull();
}
}

[SkippableFact]
public void Wrap_Null_ShouldReturnNull()
{
Expand Down

0 comments on commit e8e1ef7

Please sign in to comment.