in src/Bicep.IO/Abstraction/IOUri.cs [272:351]
private static string NormalizePath(IOUriScheme scheme, string? authority, string path)
{
if (authority is not null && !(path.Length == 0 || path.StartsWith('/')))
{
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
throw new ArgumentException("Path must be empty or absolute when authority is non-null.");
}
if (authority is null && path.StartsWith("//"))
{
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
throw new ArgumentException("Path cannot start with '//' when authority is null.");
}
if (scheme.IsFile && !path.StartsWith('/'))
{
// https://datatracker.ietf.org/doc/html/rfc8089#section-2
throw new ArgumentException("File path must be absolute.");
}
if (path.Length == 1 && path[0] == '/')
{
return path;
}
var isLocalFile = scheme.IsFile && authority == "";
var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
var stack = new Stack<string>();
for (int i = 0; i < segments.Length; i++)
{
var segment = segments[i];
if (segment == ".")
{
continue;
}
if (segment == "..")
{
if (stack.Count > 0)
{
stack.Pop();
}
}
else
{
if (isLocalFile && OperatingSystem.IsWindows())
{
var fileName = segment;
if (i == segments.Length - 1 && fileName.LastIndexOf('.') is var extensionStartIndex && extensionStartIndex >= 0)
{
fileName = fileName[..extensionStartIndex];
}
if (FilePathFacts.IsWindowsReservedFileName(fileName))
{
throw new IOException("The specified path contains unsupported Windows reserved file name.");
}
}
stack.Push(segment);
}
}
var normalizedPath = string.Join("/", stack.Reverse());
if (path.StartsWith('/'))
{
normalizedPath = '/' + normalizedPath;
}
if (path.EndsWith('/'))
{
normalizedPath += '/';
}
return normalizedPath;
}