[Windows] NSString.standardizingPath and relative symlinks

// file is symlink with relative path `../file`
print(("g:\\Projects\\SourceryDeps\\PathKit\\Tests\\PathKitTests\\Fixtures\\symlinks\\file" as NSString).standardizingPath)


Is this correct behaviour? Doesn't standardizingPath supposed to remove ..? @compnerd

That looks like correct behavior as that code isn't going through NSURL. What does:

print(URL(fileURLWithPath: ...)
              .withUnsafeFileSystemRepresentation {
  String(cString: $0)

give you?

It gives: g:\Projects\SourceryDeps\PathKit\Tests\PathKitTests\Fixtures\file If resolvingSymlinksInPath removed result is the same as with NSString.

Also it behaves differently on macOS:

Welcome to Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28).
Type :help for assistance.
  1> import Foundation
  2> let s: NSString = "/Users/hemet/Documents/Projects/PathKit/Tests/PathKitTests/Fixtures/symlinks/file"
s: NSMutableString = "/Users/hemet/Documents/Projects/PathKit/Tests/PathKitTests/Fixtures/symlinks/file"
  3> s.standardizingPath
$R0: String = "/Users/hemet/Documents/Projects/PathKit/Tests/PathKitTests/Fixtures/symlinks/file"

@compnerd Please, could you confirm this is expected behavior for standardizingPath?

I think that @millenomi would be better suited to answering whether the behaviour of NSString is expected.

That said, I suspect that this has something to do with the fact that this isn't going through the URL case as the path that you said it returns normally is being constructed lexically - everything before \file is in the internal representation and the relative path was suffixed. I think that the path handling should go through NSURL and be canonicalized through that implementation.

If this is not what Foundation is supposed to do (which @millenomi can verify) then I would say that this is a bug that we should try to get fixed.

1 Like