diff options
| author | Michael Albinus | 2018-01-31 15:02:46 +0100 |
|---|---|---|
| committer | Michael Albinus | 2018-01-31 15:02:46 +0100 |
| commit | 84d066a73fc4191a675c87c81ec1a4f531375e95 (patch) | |
| tree | 8afdbd551f972a149e69c999f9f0e088994cf229 | |
| parent | 843f3d4f34c2f54fac19d97c32399671f98ccc51 (diff) | |
| download | emacs-84d066a73fc4191a675c87c81ec1a4f531375e95.tar.gz emacs-84d066a73fc4191a675c87c81ec1a4f531375e95.zip | |
Fix Bug#30293
* lisp/net/tramp-archive.el (tramp-archive-file-name-for-operation):
New defsubst.
(tramp-archive-file-name-archive, tramp-archive-file-name-localname):
New defuns.
(tramp-archive-file-name-handler, tramp-archive-dissect-file-name)
(tramp-archive-handle-not-implemented): Use them. (Bug#30293)
* test/lisp/net/tramp-archive-tests.el (tramp-archive-test-directory):
New defconst.
(tramp-archive-test01-file-name-syntax): Extend test.
(tramp-archive-test05-expand-file-name-non-archive-directory):
New test. (Bug#30293)
* test/lisp/net/tramp-archive-resources/foo.iso/foo: New file.
| -rw-r--r-- | lisp/net/tramp-archive.el | 49 | ||||
| -rw-r--r-- | test/lisp/net/tramp-archive-resources/foo.iso/foo | 1 | ||||
| -rw-r--r-- | test/lisp/net/tramp-archive-tests.el | 59 |
3 files changed, 94 insertions, 15 deletions
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el index 51ee18fac7a..8d292e16023 100644 --- a/lisp/net/tramp-archive.el +++ b/lisp/net/tramp-archive.el | |||
| @@ -253,21 +253,33 @@ It must be supported by libarchive(3).") | |||
| 253 | "Alist of handler functions for GVFS archive method. | 253 | "Alist of handler functions for GVFS archive method. |
| 254 | Operations not mentioned here will be handled by the default Emacs primitives.") | 254 | Operations not mentioned here will be handled by the default Emacs primitives.") |
| 255 | 255 | ||
| 256 | (defsubst tramp-archive-file-name-for-operation (operation &rest args) | ||
| 257 | "Like `tramp-file-name-for-operation', but for archive file name syntax." | ||
| 258 | (cl-letf (((symbol-function 'tramp-tramp-file-p) 'tramp-archive-file-name-p)) | ||
| 259 | (apply 'tramp-file-name-for-operation operation args))) | ||
| 260 | |||
| 256 | ;;;###tramp-autoload | 261 | ;;;###tramp-autoload |
| 257 | (defun tramp-archive-file-name-handler (operation &rest args) | 262 | (defun tramp-archive-file-name-handler (operation &rest args) |
| 258 | "Invoke the GVFS archive related OPERATION. | 263 | "Invoke the GVFS archive related OPERATION. |
| 259 | First arg specifies the OPERATION, second arg is a list of arguments to | 264 | First arg specifies the OPERATION, second arg is a list of arguments to |
| 260 | pass to the OPERATION." | 265 | pass to the OPERATION." |
| 261 | (unless tramp-gvfs-enabled | 266 | (let* ((filename (apply 'tramp-archive-file-name-for-operation |
| 262 | (tramp-compat-user-error nil "Package `tramp-archive' not supported")) | 267 | operation args)) |
| 263 | (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods)) | 268 | (archive (tramp-archive-file-name-archive filename))) |
| 264 | (tramp-gvfs-methods tramp-archive-all-gvfs-methods) | 269 | ;; The file archive could be a directory, see Bug#30293. |
| 265 | (fn (assoc operation tramp-archive-file-name-handler-alist))) | 270 | (if (file-directory-p archive) |
| 266 | (when (eq (cdr fn) 'tramp-archive-handle-not-implemented) | 271 | (tramp-run-real-handler operation args) |
| 267 | (setq args (cons operation args))) | 272 | ;; Now run the handler. |
| 268 | (if fn | 273 | (unless tramp-gvfs-enabled |
| 269 | (save-match-data (apply (cdr fn) args)) | 274 | (tramp-compat-user-error nil "Package `tramp-archive' not supported")) |
| 270 | (tramp-run-real-handler operation args)))) | 275 | (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods)) |
| 276 | (tramp-gvfs-methods tramp-archive-all-gvfs-methods) | ||
| 277 | (fn (assoc operation tramp-archive-file-name-handler-alist))) | ||
| 278 | (when (eq (cdr fn) 'tramp-archive-handle-not-implemented) | ||
| 279 | (setq args (cons operation args))) | ||
| 280 | (if fn | ||
| 281 | (save-match-data (apply (cdr fn) args)) | ||
| 282 | (tramp-run-real-handler operation args)))))) | ||
| 271 | 283 | ||
| 272 | ;; Mark `operations' the handler is responsible for. | 284 | ;; Mark `operations' the handler is responsible for. |
| 273 | (put 'tramp-archive-file-name-handler 'operations | 285 | (put 'tramp-archive-file-name-handler 'operations |
| @@ -300,6 +312,16 @@ pass to the OPERATION." | |||
| 300 | (string-match tramp-archive-file-name-regexp name) | 312 | (string-match tramp-archive-file-name-regexp name) |
| 301 | t)) | 313 | t)) |
| 302 | 314 | ||
| 315 | (defun tramp-archive-file-name-archive (name) | ||
| 316 | "Return archive part of NAME." | ||
| 317 | (and (tramp-archive-file-name-p name) | ||
| 318 | (match-string 1 name))) | ||
| 319 | |||
| 320 | (defun tramp-archive-file-name-localname (name) | ||
| 321 | "Return localname part of NAME." | ||
| 322 | (and (tramp-archive-file-name-p name) | ||
| 323 | (match-string 2 name))) | ||
| 324 | |||
| 303 | (defvar tramp-archive-hash (make-hash-table :test 'equal) | 325 | (defvar tramp-archive-hash (make-hash-table :test 'equal) |
| 304 | "Hash table for archive local copies. | 326 | "Hash table for archive local copies. |
| 305 | The hash key is the archive name. The value is a cons of the | 327 | The hash key is the archive name. The value is a cons of the |
| @@ -314,9 +336,8 @@ name is kept in slot `hop'" | |||
| 314 | (save-match-data | 336 | (save-match-data |
| 315 | (unless (tramp-archive-file-name-p name) | 337 | (unless (tramp-archive-file-name-p name) |
| 316 | (tramp-compat-user-error nil "Not an archive file name: \"%s\"" name)) | 338 | (tramp-compat-user-error nil "Not an archive file name: \"%s\"" name)) |
| 317 | ;; The `string-match' happened in `tramp-archive-file-name-p'. | 339 | (let* ((localname (tramp-archive-file-name-localname name)) |
| 318 | (let* ((localname (match-string 2 name)) | 340 | (archive (file-truename (tramp-archive-file-name-archive name))) |
| 319 | (archive (file-truename (match-string 1 name))) | ||
| 320 | (vec (make-tramp-file-name | 341 | (vec (make-tramp-file-name |
| 321 | :method tramp-archive-method :hop archive))) | 342 | :method tramp-archive-method :hop archive))) |
| 322 | 343 | ||
| @@ -535,7 +556,7 @@ offered." | |||
| 535 | "Generic handler for operations not implemented for file archives." | 556 | "Generic handler for operations not implemented for file archives." |
| 536 | (let ((v (ignore-errors | 557 | (let ((v (ignore-errors |
| 537 | (tramp-archive-dissect-file-name | 558 | (tramp-archive-dissect-file-name |
| 538 | (apply 'tramp-file-name-for-operation operation args))))) | 559 | (apply 'tramp-archive-file-name-for-operation operation args))))) |
| 539 | (tramp-message v 10 "%s" (cons operation args)) | 560 | (tramp-message v 10 "%s" (cons operation args)) |
| 540 | (tramp-error | 561 | (tramp-error |
| 541 | v 'file-error | 562 | v 'file-error |
diff --git a/test/lisp/net/tramp-archive-resources/foo.iso/foo b/test/lisp/net/tramp-archive-resources/foo.iso/foo new file mode 100644 index 00000000000..257cc5642cb --- /dev/null +++ b/test/lisp/net/tramp-archive-resources/foo.iso/foo | |||
| @@ -0,0 +1 @@ | |||
| foo | |||
diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el index ecfee0c556c..96c6a71097c 100644 --- a/test/lisp/net/tramp-archive-tests.el +++ b/test/lisp/net/tramp-archive-tests.el | |||
| @@ -46,6 +46,11 @@ | |||
| 46 | (file-name-as-directory tramp-archive-test-file-archive) | 46 | (file-name-as-directory tramp-archive-test-file-archive) |
| 47 | "The test archive.") | 47 | "The test archive.") |
| 48 | 48 | ||
| 49 | (defconst tramp-archive-test-directory | ||
| 50 | (file-truename | ||
| 51 | (expand-file-name "foo.iso" tramp-archive-test-resource-directory)) | ||
| 52 | "A directory file name, which looks like an archive.") | ||
| 53 | |||
| 49 | (setq password-cache-expiry nil | 54 | (setq password-cache-expiry nil |
| 50 | tramp-verbose 0 | 55 | tramp-verbose 0 |
| 51 | tramp-cache-read-persistent-data t ;; For auth-sources. | 56 | tramp-cache-read-persistent-data t ;; For auth-sources. |
| @@ -94,14 +99,51 @@ variables, so we check the Emacs version directly." | |||
| 94 | "Check archive file name syntax." | 99 | "Check archive file name syntax." |
| 95 | (should-not (tramp-archive-file-name-p tramp-archive-test-file-archive)) | 100 | (should-not (tramp-archive-file-name-p tramp-archive-test-file-archive)) |
| 96 | (should (tramp-archive-file-name-p tramp-archive-test-archive)) | 101 | (should (tramp-archive-file-name-p tramp-archive-test-archive)) |
| 102 | (should | ||
| 103 | (string-equal | ||
| 104 | (tramp-archive-file-name-archive tramp-archive-test-archive) | ||
| 105 | tramp-archive-test-file-archive)) | ||
| 106 | (should | ||
| 107 | (string-equal | ||
| 108 | (tramp-archive-file-name-localname tramp-archive-test-archive) "/")) | ||
| 97 | (should (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo"))) | 109 | (should (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo"))) |
| 98 | (should | 110 | (should |
| 111 | (string-equal | ||
| 112 | (tramp-archive-file-name-localname | ||
| 113 | (concat tramp-archive-test-archive "foo")) | ||
| 114 | "/foo")) | ||
| 115 | (should | ||
| 99 | (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo/bar"))) | 116 | (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo/bar"))) |
| 117 | (should | ||
| 118 | (string-equal | ||
| 119 | (tramp-archive-file-name-localname | ||
| 120 | (concat tramp-archive-test-archive "foo/bar")) | ||
| 121 | "/foo/bar")) | ||
| 100 | ;; A file archive inside a file archive. | 122 | ;; A file archive inside a file archive. |
| 101 | (should | 123 | (should |
| 102 | (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar"))) | 124 | (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar"))) |
| 103 | (should | 125 | (should |
| 104 | (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar/")))) | 126 | (string-equal |
| 127 | (tramp-archive-file-name-archive | ||
| 128 | (concat tramp-archive-test-archive "baz.tar")) | ||
| 129 | tramp-archive-test-file-archive)) | ||
| 130 | (should | ||
| 131 | (string-equal | ||
| 132 | (tramp-archive-file-name-localname | ||
| 133 | (concat tramp-archive-test-archive "baz.tar")) | ||
| 134 | "/baz.tar")) | ||
| 135 | (should | ||
| 136 | (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar/"))) | ||
| 137 | (should | ||
| 138 | (string-equal | ||
| 139 | (tramp-archive-file-name-archive | ||
| 140 | (concat tramp-archive-test-archive "baz.tar/")) | ||
| 141 | (concat tramp-archive-test-archive "baz.tar"))) | ||
| 142 | (should | ||
| 143 | (string-equal | ||
| 144 | (tramp-archive-file-name-localname | ||
| 145 | (concat tramp-archive-test-archive "baz.tar/")) | ||
| 146 | "/"))) | ||
| 105 | 147 | ||
| 106 | (ert-deftest tramp-archive-test02-file-name-dissect () | 148 | (ert-deftest tramp-archive-test02-file-name-dissect () |
| 107 | "Check archive file name components." | 149 | "Check archive file name components." |
| @@ -205,6 +247,21 @@ variables, so we check the Emacs version directly." | |||
| 205 | (should (string-equal (expand-file-name "/foo.tar/./file") "/foo.tar/file")) | 247 | (should (string-equal (expand-file-name "/foo.tar/./file") "/foo.tar/file")) |
| 206 | (should (string-equal (expand-file-name "/foo.tar/../file") "/file"))) | 248 | (should (string-equal (expand-file-name "/foo.tar/../file") "/file"))) |
| 207 | 249 | ||
| 250 | ;; This test is inspired by Bug#30293. | ||
| 251 | (ert-deftest tramp-archive-test05-expand-file-name-non-archive-directory () | ||
| 252 | "Check existing directories with archive file name syntax. | ||
| 253 | They shall still be supported" | ||
| 254 | (should (file-directory-p tramp-archive-test-directory)) | ||
| 255 | ;; `tramp-archive-file-name-p' tests only for file name syntax. It | ||
| 256 | ;; doesn't test, whether it is really a file archive. | ||
| 257 | (should | ||
| 258 | (tramp-archive-file-name-p | ||
| 259 | (file-name-as-directory tramp-archive-test-directory))) | ||
| 260 | (should | ||
| 261 | (file-directory-p (file-name-as-directory tramp-archive-test-directory))) | ||
| 262 | (should | ||
| 263 | (file-exists-p (expand-file-name "foo" tramp-archive-test-directory)))) | ||
| 264 | |||
| 208 | (ert-deftest tramp-archive-test06-directory-file-name () | 265 | (ert-deftest tramp-archive-test06-directory-file-name () |
| 209 | "Check `directory-file-name'. | 266 | "Check `directory-file-name'. |
| 210 | This checks also `file-name-as-directory', `file-name-directory', | 267 | This checks also `file-name-as-directory', `file-name-directory', |