DELETE-DIRECTORY loses when supplied an "as-file" pathname containing special characters in the name or type.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Medium
|
Jan Moringen |
Bug Description
DELETE-DIRECTORY attempts to operate on the wrong file when supplied an argument having a name or type that contains characters that have special namestring syntax:
--
$ sh ./run-sbcl.sh --no-userinit --no-sysinit
(running SBCL from: .)
This is SBCL 1.4.3.20-
More information about SBCL is available at <http://
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (setq *default-
creating directory: /tmp/delete-
#P"/tmp/
* (ensure-
"a\\*b/"
T
* (probe-file "a\\*b")
#P"/private/
* (delete-directory "a\\*b")
debugger invoked on a SB-INT:
#<THREAD "main thread" RUNNING {1001968083}>:
Could not delete directory /tmp/delete-
No such file or directory
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-
0: [ABORT] Exit debugger, returning to top level.
((LABELS SB-IMPL::DELETE-DIR :IN DELETE-DIRECTORY) #P"/tmp/
0]
--
The problem is SB-IMPL:
--
* (in-package "SB-IMPL")
#<PACKAGE "SB-IMPL">
* (directorize-
#P"/a\\\\\\*b/"
* (pathname-directory (directorize-
(:ABSOLUTE "a\\*b")
* (pathname-name "a\\*b")
"a*b"
--
Given its docstring, I'd expect DELETE-DIRECTORY to operate on the directory identified by the pathname.
I propose redefining DIRECTORIZE-
(nth-value 0 (parse-
and document that DELETE-DIRECTORY can't take a wild pathname.
Rationale: in defense of going through the "native namestring" routines, this way of doing things ensures that the result of DIRECTORIZE-
As for restricting DIRECTORIZE-
(setq p (make-pathname :defaults #p"/" :name "a" :type :wild)
d (directorize-
Since P matches #P"/a" and, say, #P"/a.b", but not, for example, #P"/ab", if it's desired that D match #P"/a/" and #P"/a.b/" and not "/ab/", the trouble is that that kind of matching in a directory is not expressible with SBCL's pathname functionality. (And I don't think it's worth entertaining adding that expressiveness for this reason.)
Other requested info:
--
$ uname -a
Darwin m5.localdomain 14.5.0 Darwin Kernel Version 14.5.0: Wed Jul 29 02:26:53 PDT 2015; root:xnu-
* *features*
(:64-BIT :64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS :BSD
:C-STACK-
:COMPARE-
:DARWIN9-OR-BETTER :FLOAT-EQL-VOPS :FP-AND-
:IEEE-
:INTEGER-EQL-VOP :LINKAGE-TABLE :LITTLE-ENDIAN :MACH-EXCEPTION
:MEMORY-
:OS-PROVIDES-
:OS-PROVIDES-
:RAW-INSTANCE-
:SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK :SB-SOURCE-
:SB-UNICODE :SBCL :STACK-
:STACK-
:STACK-
:UNBIND-N-VOP :UNDEFINED-
:X86-64)
--
Changed in sbcl: | |
assignee: | nobody → Jan Moringen (scymtym) |
status: | New → Confirmed |
importance: | Undecided → Medium |
Changed in sbcl: | |
status: | Confirmed → Fix Committed |
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
Hi Jan,
I see you've made a commit, 179bc57a, that changes the definition of DIRECTORIZE- PATHNAME to
-- pathname (pathname) pathname- p pathname) file-perror
(pathname- type pathname))
(pathname- name pathname)
(pathname- type pathname))))
(make-pathname
( list from-file)))))
(defun directorize-
(cond
((wild-
(simple-
"Cannot compute directory pathname for wild pathname ~S"
pathname))
((or (pathname-name pathname)
(let ((from-file (format nil "~@[~A~]~@[.~A~]"
:host (pathname-host pathname)
:device (pathname-device pathname)
:directory (append (pathname-directory pathname)
(t
pathname)))
--
This will produce incorrect results when the name or type is :UNSPECIFIC.
This kind of thing is why I suggested running the argument through the "native namestring" unparsing and parsing routines, as these are the only routines that implement filename denotation in SBCL. Even if this one routine can be made to agree with those other routines for now, having this extra bit of logic in one place is guaranteed to be a source of bugs as other things evolve.
Thanks,
Richard