find-executable-path: avoid conversion of PATH to string

Send bytes directly to `path-list-string->path-list`, since it can
handle bytes and convert directly to paths. Also check that the
argument to `path-list-string->path-list` has no nul character or byte.
This commit is contained in:
Matthew Flatt 2021-03-02 15:40:27 -07:00
parent 421dce228d
commit afe522ab9c
5 changed files with 26 additions and 8 deletions

View File

@ -256,13 +256,14 @@ by @racket[kind], which must be one of the following:
(listof (or/c path? 'same))]{
Parses a string or byte string containing a list of paths, and returns
a list of path strings. On @|AllUnix|, paths in a path list are
a list of paths. On @|AllUnix|, paths in a path-list string are
separated by a @litchar{:}; on Windows, paths are separated by a
@litchar{;}, and all @litchar{"}s in the string are discarded. Whenever the path
list contains an empty path, the list
@racket[default-path-list] is spliced into the returned list of
paths. Parts of @racket[str] that do not form a valid path are not
included in the returned list.
included in the returned list. The given @racket[str] must not contain
a nul character or nul byte.
@history[#:changed "8.0.0.10" @elem{Changed to allow @racket['same] in
@racket[default-path-list].}]}

View File

@ -87,8 +87,8 @@ on how strings encode paths.
path?]{
Produces a path (for some platform) whose byte-string encoding is
@racket[bstr]. The optional @racket[type] specifies the convention to
use for the path.
@racket[bstr], where @racket[bstr] must not contain a nul byte. The
optional @racket[type] specifies the convention to use for the path.
For converting relative @tech{path elements} from literals, use instead
@racket[bytes->path-element], which applies a suitable encoding for

View File

@ -1043,6 +1043,18 @@
(test "\\\\?\\q:\\tmp\\b\\UNC\\machine\\path\\x/y\\z"
reroot-path/w "\\\\?\\UNC\\machine\\path\\x/y\\z" "q:/tmp/b"))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; make sure `path-list-string->path-list` can deal with
;; bytes that (likely) don't fit into the current locale's encoding
(test (list (bytes->path #"a\200c")
(bytes->path #"def"))
path-list-string->path-list
(if (eq? (system-type) 'windows)
#"a\200c;def"
#"a\200c:def")
null)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -39,14 +39,14 @@
(if (and (relative-path? program)
(let-values ([(base name dir?) (split-path program)])
(eq? base 'relative)))
(let ([paths-str (environment-variables-ref (current-environment-variables)
#"PATH")]
(let ([paths-bstr (environment-variables-ref (current-environment-variables)
#"PATH")]
[win-add (lambda (s) (if (eq? (system-type) 'windows)
(cons (bytes->path #".") s)
s))])
(let loop ([paths (win-add
(if paths-str
(path-list-string->path-list (bytes->string/locale paths-str #\?)
(if paths-bstr
(path-list-string->path-list paths-bstr
null)
null))])
(if (null? paths)

View File

@ -26,6 +26,11 @@
(unless (or (bytes? s)
(string? s))
(raise-argument-error 'path-list-string->path-list "(or/c bytes? string?)" s))
(when (regexp-match? #rx"\0" s)
(let ([label (if (bytes? s) "byte string" "string")])
(raise-arguments-error 'path-list-string->path-list
(format "given ~a contains a nul character" label)
label s)))
(unless (and (list? default)
(andmap (lambda (p) (or (eq? p 'same) path?)) default))
(raise-argument-error 'path-list-string->path-list "(listof path?)" default))