Skip to content

Uri seems to incorrectly escape local paths containing certain Unicode characters #89538

@tmat

Description

@tmat

Description

There is a difference in the value of LocalPath property depending on whether the Uri instance is created with an absolute local path vs. URL with file scheme. For example, character U+E25B is escaped in the former and not in the latter case.

Reproduction Steps

Console.WriteLine(new Uri("c:\\\ue25b").LocalPath);
Console.WriteLine(new Uri("file://c:/\ue25b").LocalPath);

Expected behavior

c:\
c:\

Actual behavior

c:\%EE%89%9B
c:\

Regression?

No

Known Workarounds

 public static Uri CreateAbsoluteUri(string absolutePath)
 {
        return new Uri(IsAscii(absolutePath) ? absolutePath : GetAbsoluteUriString(), UriKind.Absolute);

        static string GetAbsoluteUriString()
        {
            var parts = absolutePath.Split([Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar]);

            if (Path.DirectorySeparatorChar == '/')
            {
                // Unix path: first part is empty, all parts should be escaped
                return "file://" + string.Join("/", parts.Select(EscapeUriPart));
            }

            if (parts is ["", "", var serverName, ..])
            {
                // UNC path: first non-empty part is server name and shouldn't be escaped
                return "file://" + serverName + "/" + string.Join("/", parts.Skip(3).Select(EscapeUriPart));
            }

            // Drive-rooted path: first part is "C:" and shouldn't be escaped
            return "file:///" + parts[0] + "/" + string.Join("/", parts.Skip(1).Select(EscapeUriPart));

            static string EscapeUriPart(string stringToEscape)
                => Uri.EscapeUriString(stringToEscape).Replace("#", "%23");
        }
}

Configuration

8.0.100-preview.6.23330.14 but also on .NET Framework.

Other information

No response

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions