diff --git a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl index a5d5279f0d..7a4e377198 100644 --- a/pkgs/racket-doc/scribblings/reference/filesystem.scrbl +++ b/pkgs/racket-doc/scribblings/reference/filesystem.scrbl @@ -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].}]} diff --git a/pkgs/racket-doc/scribblings/reference/paths.scrbl b/pkgs/racket-doc/scribblings/reference/paths.scrbl index a1e891ad86..a7c03088a5 100644 --- a/pkgs/racket-doc/scribblings/reference/paths.scrbl +++ b/pkgs/racket-doc/scribblings/reference/paths.scrbl @@ -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 diff --git a/pkgs/racket-test-core/tests/racket/path.rktl b/pkgs/racket-test-core/tests/racket/path.rktl index 85cc96ca54..99a577d5f5 100644 --- a/pkgs/racket-test-core/tests/racket/path.rktl +++ b/pkgs/racket-test-core/tests/racket/path.rktl @@ -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) diff --git a/racket/collects/racket/private/executable-path.rkt b/racket/collects/racket/private/executable-path.rkt index 1959177287..2cc2f12da7 100644 --- a/racket/collects/racket/private/executable-path.rkt +++ b/racket/collects/racket/private/executable-path.rkt @@ -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) diff --git a/racket/collects/racket/private/path-list.rkt b/racket/collects/racket/private/path-list.rkt index 2283d702fb..58fa08c30f 100644 --- a/racket/collects/racket/private/path-list.rkt +++ b/racket/collects/racket/private/path-list.rkt @@ -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))