os.nim: use the new pathnorm.normalizePath implementation

This commit is contained in:
Araq 2018-12-14 08:57:55 +01:00
commit ce9815bcf5
4 changed files with 67 additions and 85 deletions

View file

@ -984,36 +984,37 @@ proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [], noNimScr
##
## 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:
path = pathnorm.normalizePath(path)
when false:
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)
elif stack[^1] == "..":
stack.add(p)
else:
discard stack.pop()
else:
discard stack.pop()
else:
stack.add(p)
stack.add(p)
if isAbs:
path = DirSep & join(stack, $DirSep)
elif stack.len > 0:
path = join(stack, $DirSep)
else:
path = "."
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: [], noNimScript.} =
## Returns a normalized path for the current OS. See `<#normalizePath>`_
result = path
normalizePath(result)
result = pathnorm.normalizePath(path)
when defined(Windows) and not defined(nimscript):
proc openHandle(path: string, followSymlink=true, writeAccess=false): Handle =

View file

@ -66,19 +66,26 @@ proc addNormalizePath*(x: string; result: var string; state: var int; dirSep = D
if (state shr 1 == 0) and isSlash(x, b):
result.add dirSep
state = state or 1
elif result.len > (state and 1) and isDotDot(x, b):
var d = result.len
# f/..
while (d-1) > (state and 1) and result[d-1] notin {DirSep, AltSep}:
dec d
if d > 0: setLen(result, d-1)
elif isDotDot(x, b):
if (state shr 1) >= 1:
var d = result.len
# f/..
while (d-1) > (state and 1) and result[d-1] notin {DirSep, AltSep}:
dec d
if d > 0:
setLen(result, d-1)
dec state, 2
else:
if result.len > 0 and result[^1] notin {DirSep, AltSep}:
result.add dirSep
result.add substr(x, b[0], b[1])
elif isDot(x, b):
discard "discard the dot"
elif b[1] >= b[0]:
if result.len > 0 and result[^1] notin {DirSep, AltSep}:
result.add dirSep
result.add substr(x, b[0], b[1])
inc state, 2
inc state, 2
proc normalizePath*(path: string; dirSep = DirSep): string =
## Example: