From 406a67def6894f8ba2a4f737c52ae844b8492bc1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 24 May 2020 13:48:35 -0600 Subject: [PATCH] cs: fix `resolve-path` to preserve directory separator Closes #3212 --- pkgs/racket-test-core/tests/racket/file.rktl | 4 ++++ pkgs/racket-test-core/tests/racket/pathlib.rktl | 7 ++++++- racket/src/io/file/main.rkt | 5 +++-- racket/src/io/path/directory-path.rkt | 17 ++++++++--------- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/file.rktl b/pkgs/racket-test-core/tests/racket/file.rktl index 65e4ec79e0..7360d93662 100644 --- a/pkgs/racket-test-core/tests/racket/file.rktl +++ b/pkgs/racket-test-core/tests/racket/file.rktl @@ -2338,6 +2338,10 @@ resolve-path "C://testing-root////testing-dir\\\\testing-file")])) +(unless (link-exists? (current-directory)) + ;; Make sure directoryness is preserved + (test (current-directory) resolve-path (current-directory))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Make sure `write-byte` and `write-char` don't try to test ;; a non-supplied argument: diff --git a/pkgs/racket-test-core/tests/racket/pathlib.rktl b/pkgs/racket-test-core/tests/racket/pathlib.rktl index 5c5aa2e50d..16306541b3 100644 --- a/pkgs/racket-test-core/tests/racket/pathlib.rktl +++ b/pkgs/racket-test-core/tests/racket/pathlib.rktl @@ -105,7 +105,12 @@ ;; ---------------------------------------- -;; normalize-path needs tests +;; normalize-path needs more tests + +(unless (directory-exists? "no-such-dir-here") + (err/rt-test (normalize-path (build-path "no-such-dir-here" 'up 'up)) + exn:fail? + #rx"element within the input path is not a directory")) ;; ---------------------------------------- diff --git a/racket/src/io/file/main.rkt b/racket/src/io/file/main.rkt index 3d0e0d8015..686defd39f 100644 --- a/racket/src/io/file/main.rkt +++ b/racket/src/io/file/main.rkt @@ -344,9 +344,10 @@ (define (do-resolve-path p who) (check who path-string? p) - (define host-path (->host (path->path-without-trailing-separator (->path p)) who '(exists))) + (define host-path (->host p who '(exists))) + (define host-path/no-sep (host-path->host-path-without-trailing-separator host-path)) (start-atomic) - (define r0 (rktio_readlink rktio host-path)) + (define r0 (rktio_readlink rktio host-path/no-sep)) (define r (if (rktio-error? r0) r0 (begin0 diff --git a/racket/src/io/path/directory-path.rkt b/racket/src/io/path/directory-path.rkt index 06bfa0ba9e..dd8cb192fb 100644 --- a/racket/src/io/path/directory-path.rkt +++ b/racket/src/io/path/directory-path.rkt @@ -7,7 +7,7 @@ (provide directory-path? path->directory-path - path->path-without-trailing-separator) + host-path->host-path-without-trailing-separator) (define/who (path->directory-path p-in) (check-path-argument who p-in) @@ -53,16 +53,15 @@ dots-end))))] [else (unixish-path-directory-path?)])])) -(define (path->path-without-trailing-separator p) - (define bstr (path-bytes p)) +(define (host-path->host-path-without-trailing-separator bstr) (define orig-len (bytes-length bstr)) (cond - [(= orig-len 1) p] - [(and (eq? (path-convention p) 'windows) + [(= orig-len 1) bstr] + [(and (eq? (system-path-convention-type) 'windows) (backslash-backslash-questionmark? bstr)) ;; \\?\ is more complicated. Do we need to do anything, ;; considering that the use for this function is `resolve-path`? - p] + bstr] [else (define len (let loop ([len orig-len]) @@ -70,9 +69,9 @@ [(zero? len) 0] [else (define c (bytes-ref bstr (sub1 len))) - (if (is-sep? c (path-convention p)) + (if (is-sep? c (system-path-convention-type)) (loop (sub1 len)) len)]))) (cond - [(< len orig-len) (path (subbytes bstr 0 len) (path-convention p))] - [else p])])) + [(< len orig-len) (subbytes bstr 0 len)] + [else bstr])]))