aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Stephani2020-12-13 17:13:50 +0100
committerPhilipp Stephani2020-12-13 17:17:21 +0100
commitfe50a8b9ba79b4ac14a3a352d8bf84eaee4f2122 (patch)
tree0b0b990f0f49f2ad652c2506caa7e5b15add75a3
parent897b8561cdc856fb40b2a3c6f29230849aaf4a34 (diff)
downloademacs-fe50a8b9ba79b4ac14a3a352d8bf84eaee4f2122.tar.gz
emacs-fe50a8b9ba79b4ac14a3a352d8bf84eaee4f2122.zip
Byte compilation: handle case where the output file is a mountpoint.
See Bug#44631. While testing for a readonly output directory has slightly different semantics, in practice they should cover cases where Emacs is sandboxed and can only write to the destination file, not its directory. * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Handle the case where the output directory is not writable. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--not-writable-directory) (bytecomp-tests--dest-mountpoint): New unit tests.
-rw-r--r--lisp/emacs-lisp/bytecomp.el14
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el69
2 files changed, 82 insertions, 1 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 51accc08654..e23bb9f5e6e 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1963,7 +1963,11 @@ See also `emacs-lisp-byte-compile-and-load'."
1963 (insert "\n") ; aaah, unix. 1963 (insert "\n") ; aaah, unix.
1964 (cond 1964 (cond
1965 ((null target-file) nil) ;We only wanted the warnings! 1965 ((null target-file) nil) ;We only wanted the warnings!
1966 ((file-writable-p target-file) 1966 ((and (file-writable-p target-file)
1967 ;; We attempt to create a temporary file in the
1968 ;; target directory, so the target directory must be
1969 ;; writable.
1970 (file-writable-p (file-name-directory target-file)))
1967 ;; We must disable any code conversion here. 1971 ;; We must disable any code conversion here.
1968 (let* ((coding-system-for-write 'no-conversion) 1972 (let* ((coding-system-for-write 'no-conversion)
1969 ;; Write to a tempfile so that if another Emacs 1973 ;; Write to a tempfile so that if another Emacs
@@ -1992,6 +1996,14 @@ See also `emacs-lisp-byte-compile-and-load'."
1992 ;; deleting target-file before writing it. 1996 ;; deleting target-file before writing it.
1993 (rename-file tempfile target-file t)) 1997 (rename-file tempfile target-file t))
1994 (or noninteractive (message "Wrote %s" target-file))) 1998 (or noninteractive (message "Wrote %s" target-file)))
1999 ((file-writable-p target-file)
2000 ;; In case the target directory isn't writable (see e.g. Bug#44631),
2001 ;; try writing to the output file directly. We must disable any
2002 ;; code conversion here.
2003 (let ((coding-system-for-write 'no-conversion))
2004 (with-file-modes (logand (default-file-modes) #o666)
2005 (write-region (point-min) (point-max) target-file nil 1)))
2006 (or noninteractive (message "Wrote %s" target-file)))
1995 (t 2007 (t
1996 ;; This is just to give a better error message than write-region 2008 ;; This is just to give a better error message than write-region
1997 (let ((exists (file-exists-p target-file))) 2009 (let ((exists (file-exists-p target-file)))
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index 8fa4d278f11..c2a3e3ba117 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -947,6 +947,75 @@ literals (Bug#20852)."
947 '((suspicious set-buffer)) 947 '((suspicious set-buffer))
948 "Warning: Use .with-current-buffer. rather than")) 948 "Warning: Use .with-current-buffer. rather than"))
949 949
950(ert-deftest bytecomp-tests--not-writable-directory ()
951 "Test that byte compilation works if the output directory isn't
952writable (Bug#44631)."
953 (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
954 (unwind-protect
955 (let* ((input-file (expand-file-name "test.el" directory))
956 (output-file (expand-file-name "test.elc" directory))
957 (byte-compile-dest-file-function
958 (lambda (_) output-file))
959 (byte-compile-error-on-warn t))
960 (write-region "" nil input-file nil nil nil 'excl)
961 (write-region "" nil output-file nil nil nil 'excl)
962 (set-file-modes input-file #o400)
963 (set-file-modes output-file #o200)
964 (set-file-modes directory #o500)
965 (should (byte-compile-file input-file))
966 (should (file-regular-p output-file))
967 (should (cl-plusp (file-attribute-size
968 (file-attributes output-file)))))
969 (with-demoted-errors "Error cleaning up directory: %s"
970 (set-file-modes directory #o700)
971 (delete-directory directory :recursive)))))
972
973(ert-deftest bytecomp-tests--dest-mountpoint ()
974 "Test that byte compilation works if the destination file is a
975mountpoint (Bug#44631)."
976 (let ((bwrap (executable-find "bwrap"))
977 (emacs (expand-file-name invocation-name invocation-directory)))
978 (skip-unless bwrap)
979 (skip-unless (file-executable-p bwrap))
980 (skip-unless (not (file-remote-p bwrap)))
981 (skip-unless (file-executable-p emacs))
982 (skip-unless (not (file-remote-p emacs)))
983 (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
984 (unwind-protect
985 (let* ((input-file (expand-file-name "test.el" directory))
986 (output-file (expand-file-name "test.elc" directory))
987 (unquoted-file (file-name-unquote output-file))
988 (byte-compile-dest-file-function
989 (lambda (_) output-file))
990 (byte-compile-error-on-warn t))
991 (should-not (file-remote-p input-file))
992 (should-not (file-remote-p output-file))
993 (write-region "" nil input-file nil nil nil 'excl)
994 (write-region "" nil output-file nil nil nil 'excl)
995 (set-file-modes input-file #o400)
996 (set-file-modes output-file #o200)
997 (set-file-modes directory #o500)
998 (with-temp-buffer
999 (let ((status (call-process
1000 bwrap nil t nil
1001 "--ro-bind" "/" "/"
1002 "--bind" unquoted-file unquoted-file
1003 emacs "--quick" "--batch" "--load=bytecomp"
1004 (format "--eval=%S"
1005 `(setq byte-compile-dest-file-function
1006 (lambda (_) ,output-file)
1007 byte-compile-error-on-warn t))
1008 "--funcall=batch-byte-compile" input-file)))
1009 (unless (eql status 0)
1010 (ert-fail `((status . ,status)
1011 (output . ,(buffer-string)))))))
1012 (should (file-regular-p output-file))
1013 (should (cl-plusp (file-attribute-size
1014 (file-attributes output-file)))))
1015 (with-demoted-errors "Error cleaning up directory: %s"
1016 (set-file-modes directory #o700)
1017 (delete-directory directory :recursive))))))
1018
950;; Local Variables: 1019;; Local Variables:
951;; no-byte-compile: t 1020;; no-byte-compile: t
952;; End: 1021;; End: