1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 14:30:50 -08:00

Fix make-temp-file bug with ""/"."/".." prefix

The bug with "." and ".." has been present for a while; I
introduced the bug with "" earlier today in my patch for Bug#28023.
* lisp/files.el (make-temp-file): Do not use expand-file-name if
PREFIX is empty or "." or "..", as it does the wrong thing.
Compute absolute-prefix here ...
(files--make-magic-temp-file): ... instead of here ...
* src/fileio.c (Fmake_temp_file_internal): ... or here.

* lisp/files.el (make-temp-file): If the prefix is empty, append
"/" to the absolute prefix so that the new files are children
rather than siblings of temporary-file-directory.  This fixes a
bug introduced in the previous change.
* test/lisp/files-tests.el (files-test-make-temp-file-empty-prefix):
New test, for the bug.
This commit is contained in:
Paul Eggert 2017-08-12 20:04:43 -07:00
parent a6ad98ad66
commit ebf53ed4f6
3 changed files with 26 additions and 16 deletions

View file

@ -1407,14 +1407,17 @@ You can then use `write-region' to write new data into the file.
If DIR-FLAG is non-nil, create a new empty directory instead of a file. If DIR-FLAG is non-nil, create a new empty directory instead of a file.
If SUFFIX is non-nil, add that at the end of the file name." If SUFFIX is non-nil, add that at the end of the file name."
(let ((absolute-prefix (expand-file-name prefix temporary-file-directory))) (let ((absolute-prefix
(if (or (zerop (length prefix)) (member prefix '("." "..")))
(concat (file-name-as-directory temporary-file-directory) prefix)
(expand-file-name prefix temporary-file-directory))))
(if (find-file-name-handler absolute-prefix 'write-region) (if (find-file-name-handler absolute-prefix 'write-region)
(files--make-magic-temp-file prefix dir-flag suffix) (files--make-magic-temp-file absolute-prefix dir-flag suffix)
(make-temp-file-internal absolute-prefix (make-temp-file-internal absolute-prefix
(if dir-flag t) (or suffix ""))))) (if dir-flag t) (or suffix "")))))
(defun files--make-magic-temp-file (prefix &optional dir-flag suffix) (defun files--make-magic-temp-file (absolute-prefix &optional dir-flag suffix)
"Implement (make-temp-file PREFIX DIR-FLAG SUFFIX). "Implement (make-temp-file ABSOLUTE-PREFIX DIR-FLAG SUFFIX).
This implementation works on magic file names." This implementation works on magic file names."
;; Create temp files with strict access rights. It's easy to ;; Create temp files with strict access rights. It's easy to
;; loosen them later, whereas it's impossible to close the ;; loosen them later, whereas it's impossible to close the
@ -1423,13 +1426,7 @@ This implementation works on magic file names."
(let (file) (let (file)
(while (condition-case () (while (condition-case ()
(progn (progn
(setq file (setq file (make-temp-name absolute-prefix))
(make-temp-name
(if (zerop (length prefix))
(file-name-as-directory
temporary-file-directory)
(expand-file-name prefix
temporary-file-directory))))
(if suffix (if suffix
(setq file (concat file suffix))) (setq file (concat file suffix)))
(if dir-flag (if dir-flag

View file

@ -662,17 +662,16 @@ DEFUN ("make-temp-file-internal", Fmake_temp_file_internal,
Return the name of the generated file. If DIR-FLAG is zero, do not Return the name of the generated file. If DIR-FLAG is zero, do not
create the file, just its name. Otherwise, if DIR-FLAG is non-nil, create the file, just its name. Otherwise, if DIR-FLAG is non-nil,
create an empty directory. The file name should end in SUFFIX. create an empty directory. The file name should end in SUFFIX.
Do not expand PREFIX; a non-absolute PREFIX is relative to the Emacs
working directory.
Signal an error if the file could not be created. Signal an error if the file could not be created.
This function does not grok magic file names. */) This function does not grok magic file names. */)
(Lisp_Object prefix, Lisp_Object dir_flag, Lisp_Object suffix) (Lisp_Object prefix, Lisp_Object dir_flag, Lisp_Object suffix)
{ {
bool make_temp_name = EQ (dir_flag, make_number (0)); CHECK_STRING (prefix);
CHECK_STRING (suffix); CHECK_STRING (suffix);
if (!make_temp_name)
prefix = Fexpand_file_name (prefix, Vtemporary_file_directory);
Lisp_Object encoded_prefix = ENCODE_FILE (prefix); Lisp_Object encoded_prefix = ENCODE_FILE (prefix);
Lisp_Object encoded_suffix = ENCODE_FILE (suffix); Lisp_Object encoded_suffix = ENCODE_FILE (suffix);
ptrdiff_t prefix_len = SBYTES (encoded_prefix); ptrdiff_t prefix_len = SBYTES (encoded_prefix);
@ -686,7 +685,7 @@ This function does not grok magic file names. */)
memset (data + prefix_len, 'X', nX); memset (data + prefix_len, 'X', nX);
memcpy (data + prefix_len + nX, SSDATA (encoded_suffix), suffix_len); memcpy (data + prefix_len + nX, SSDATA (encoded_suffix), suffix_len);
int kind = (NILP (dir_flag) ? GT_FILE int kind = (NILP (dir_flag) ? GT_FILE
: make_temp_name ? GT_NOCREATE : EQ (dir_flag, make_number (0)) ? GT_NOCREATE
: GT_DIR); : GT_DIR);
int fd = gen_tempname (data, suffix_len, O_BINARY | O_CLOEXEC, kind); int fd = gen_tempname (data, suffix_len, O_BINARY | O_CLOEXEC, kind);
if (fd < 0 || (NILP (dir_flag) && emacs_close (fd) != 0)) if (fd < 0 || (NILP (dir_flag) && emacs_close (fd) != 0))

View file

@ -166,6 +166,20 @@ form.")
(should (eq buffer-file-coding-system 'iso-2022-7bit-unix)))) (should (eq buffer-file-coding-system 'iso-2022-7bit-unix))))
(delete-file tempfile)))) (delete-file tempfile))))
(ert-deftest files-test-make-temp-file-empty-prefix ()
"Test make-temp-file with an empty prefix."
(let ((tempfile (make-temp-file ""))
(tempdir (make-temp-file "" t))
(tempfile-. (make-temp-file "."))
(tempdir-. (make-temp-file "." t))
(tempfile-.. (make-temp-file ".."))
(tempdir-.. (make-temp-file ".." t)))
(dolist (file (list tempfile tempfile-. tempfile-..))
(should file)
(delete-file file))
(dolist (dir (list tempdir tempdir-. tempdir-..))
(should dir)
(delete-directory dir))))
;; Stop the above "Local Var..." confusing Emacs. ;; Stop the above "Local Var..." confusing Emacs.