Skip to content

Commit b05d8f1

Browse files
authored
fix: InvalidInputFile error occurs if file contains URI escaped charactors (dotnet#9700)
* fix: InvalidInputFile error occurs if file contains URI escaped characters * chore: remove not redundant setting.
1 parent be1e4fa commit b05d8f1

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

src/Docfx.Common/Path/PathUtility.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ public static string MakeRelativePath(string basePath, string absolutePath)
6969
return absolutePath;
7070
}
7171

72-
Uri relativeUri = fromUri.MakeRelativeUri(toUri);
73-
string relativePath = Uri.UnescapeDataString(relativeUri.ToString());
74-
75-
if (string.Equals(toUri.Scheme, "FILE", StringComparison.InvariantCultureIgnoreCase))
72+
if (toUri.IsFile && !toUri.OriginalString.StartsWith("file://", StringComparison.InvariantCultureIgnoreCase))
7673
{
77-
relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
74+
return Path.GetRelativePath(basePath, absolutePath).BackSlashToForwardSlash();
7875
}
7976

77+
Uri relativeUri = fromUri.MakeRelativeUri(toUri);
78+
string relativePath = Uri.UnescapeDataString(relativeUri.ToString());
79+
8080
return relativePath.BackSlashToForwardSlash();
8181
}
8282

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using FluentAssertions;
5+
using Xunit;
6+
7+
namespace Docfx.Common.Tests;
8+
9+
public class PathUtilityTest
10+
{
11+
[Theory]
12+
[MemberData(nameof(TestData.AdditionalTests), MemberType = typeof(TestData))]
13+
public void TestMakeRelativePath(string basePath, string targetPath, string expected)
14+
{
15+
// Act
16+
var result = PathUtility.MakeRelativePath(basePath, targetPath);
17+
18+
// Assert
19+
result.Should().Be(expected);
20+
}
21+
22+
[Theory]
23+
[MemberData(nameof(TestData.EscapedPaths), MemberType = typeof(TestData))]
24+
public void TestMakeRelativePathWithEncodedPath(string inputPath)
25+
{
26+
// Arrange
27+
string basePath = "./";
28+
var expected = inputPath;
29+
30+
// Act
31+
var result = PathUtility.MakeRelativePath(basePath, inputPath);
32+
33+
// Assert
34+
result.Should().Be(expected);
35+
}
36+
37+
private static class TestData
38+
{
39+
public static TheoryData<string, string, string> AdditionalTests = new()
40+
{
41+
{ @"/a/b/d", @"/a/b/file.md", @"../file.md"}, // root relative path
42+
{ @"~/a/b/d", @"~/a/b/file.md", @"../file.md"}, // user home directory relative path
43+
{ @"./", @"\\UNCPath\file.md", @"//UNCPath/file.md"}, // UNC path
44+
{ @"./", @"file:///C:/temp/test.md", @"file:/C:/temp/test.md"}, // `file:` Uri path
45+
{ @"file:///C:/temp", @"file:///C:/temp/test.md", @"test.md"}, // `file:` Uri relative path
46+
{ @"/temp/dir", @"/temp/dir/subdir/", @"subdir/"}, // If target path endsWith directory separator char. resolved path should contain directory separator.
47+
};
48+
49+
public static TheoryData<string> EscapedPaths = new()
50+
{
51+
"EscapedHypen(%2D).md", // Contains escaped hypen char
52+
"EscapedSpace(%20)_with_NonAsciiChar(α).md", // Contains escaped space char and non-unicode char
53+
};
54+
}
55+
}

0 commit comments

Comments
 (0)