Merge pull request #6587 from FedericoCeratto/normalizePath

Add normalizePath and tests
This commit is contained in:
Dominik Picheta
2018-07-07 10:12:07 +01:00
committed by GitHub
2 changed files with 105 additions and 2 deletions

View File

@@ -298,8 +298,8 @@ proc setCurrentDir*(newDir: string) {.inline, tags: [].} =
proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
tags: [ReadDirEffect].} =
## Returns the full (`absolute`:idx:) path of the file `filename`,
## raises OSError in case of an error.
## Returns the full (`absolute`:idx:) path of an existing file `filename`,
## raises OSError in case of an error. Follows symlinks.
when defined(windows):
var bufsize = MAX_PATH.int32
when useWinUnicode:
@@ -338,6 +338,47 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
result = $r
c_free(cast[pointer](r))
proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [].} =
## Normalize a path.
##
## Consecutive directory separators are collapsed, including an initial double slash.
##
## On relative paths, double dot (..) sequences are collapsed if possible.
## On absolute paths they are always collapsed.
##
## Warning: URL-encoded and Unicode attempts at directory traversal are not detected.
## Triple dot is not handled.
let isAbs = isAbsolute(path)
var stack: seq[string] = @[]
for p in split(path, {DirSep}):
case p
of "", ".":
continue
of "..":
if stack.len == 0:
if isAbs:
discard # collapse all double dots on absoluta paths
else:
stack.add(p)
elif stack[^1] == "..":
stack.add(p)
else:
discard stack.pop()
else:
stack.add(p)
if isAbs:
path = DirSep & join(stack, $DirSep)
elif stack.len > 0:
path = join(stack, $DirSep)
else:
path = "."
proc normalizedPath*(path: string): string {.rtl, extern: "nos$1", tags: [].} =
## Returns a normalized path for the current OS. See `<#normalizePath>`_
result = path
normalizePath(result)
when defined(Windows):
proc openHandle(path: string, followSymlink=true, writeAccess=false): Handle =
var flags = FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL