Mercurial > emacs
comparison lisp/tar-mode.el @ 102525:438d27553e81
(tar-header-block-tokenize): Presume less, check more.
(tar-summarize-buffer): Don't silently skip incomplete headers.
(tar-mode): Revert to fundamental-mode in case of malformed tar data.
(tar-extract): Try to make sure set-auto-mode doesn't mistakenly
treat a tar file member as being a tar file itself, just because
its own filename includes the parent tar file's.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 13 Mar 2009 15:37:03 +0000 |
parents | be5a7a68d09d |
children | f4adb8b6af6c |
comparison
equal
deleted
inserted
replaced
102524:cec89dff31fa | 102525:438d27553e81 |
---|---|
224 | 224 |
225 (defun tar-header-block-tokenize (pos coding) | 225 (defun tar-header-block-tokenize (pos coding) |
226 "Return a `tar-header' structure. | 226 "Return a `tar-header' structure. |
227 This is a list of name, mode, uid, gid, size, | 227 This is a list of name, mode, uid, gid, size, |
228 write-date, checksum, link-type, and link-name." | 228 write-date, checksum, link-type, and link-name." |
229 (assert (<= (+ pos 512) (point-max))) | 229 (if (> (+ pos 512) (point-max)) (error "Malformed Tar header")) |
230 (assert (zerop (mod (- pos (point-min)) 512))) | 230 (assert (zerop (mod (- pos (point-min)) 512))) |
231 (assert (not enable-multibyte-characters)) | 231 (assert (not enable-multibyte-characters)) |
232 (let ((string (buffer-substring pos (setq pos (+ pos 512))))) | 232 (let ((string (buffer-substring pos (setq pos (+ pos 512))))) |
233 (when ;(some 'plusp string) ; <-- oops, massive cycle hog! | 233 (when ;(some 'plusp string) ; <-- oops, massive cycle hog! |
234 (or (not (= 0 (aref string 0))) ; This will do. | 234 (or (not (= 0 (aref string 0))) ; This will do. |
481 (with-current-buffer tar-data-buffer | 481 (with-current-buffer tar-data-buffer |
482 (make-progress-reporter "Parsing tar file..." | 482 (make-progress-reporter "Parsing tar file..." |
483 (point-min) (point-max)))) | 483 (point-min) (point-max)))) |
484 descriptor) | 484 descriptor) |
485 (with-current-buffer tar-data-buffer | 485 (with-current-buffer tar-data-buffer |
486 (while (and (<= (+ pos 512) (point-max)) | 486 (while (and (< pos (point-max)) |
487 (setq descriptor (tar-header-block-tokenize pos coding))) | 487 (setq descriptor (tar-header-block-tokenize pos coding))) |
488 (let ((size (tar-header-size descriptor))) | 488 (let ((size (tar-header-size descriptor))) |
489 (if (< size 0) | 489 (if (< size 0) |
490 (error "%s has size %s - corrupted" | 490 (error "%s has size %s - corrupted" |
491 (tar-header-name descriptor) size))) | 491 (tar-header-name descriptor) size))) |
652 (set-buffer-multibyte nil) ;Hopefully a no-op. | 652 (set-buffer-multibyte nil) ;Hopefully a no-op. |
653 (set (make-local-variable 'tar-data-buffer) | 653 (set (make-local-variable 'tar-data-buffer) |
654 (generate-new-buffer (format " *tar-data %s*" | 654 (generate-new-buffer (format " *tar-data %s*" |
655 (file-name-nondirectory | 655 (file-name-nondirectory |
656 (or buffer-file-name (buffer-name)))))) | 656 (or buffer-file-name (buffer-name)))))) |
657 (tar-swap-data) | 657 (condition-case err |
658 (tar-summarize-buffer) | 658 (progn |
659 (tar-next-line 0)) | 659 (tar-swap-data) |
660 (tar-summarize-buffer) | |
661 (tar-next-line 0)) | |
662 (error | |
663 ;; If summarizing caused an error, then maybe the buffer doesn't contain | |
664 ;; tar data. Rather than show a mysterious empty buffer, let's | |
665 ;; revert to fundamental-mode. | |
666 (fundamental-mode) | |
667 (signal (car err) (cdr err))))) | |
660 | 668 |
661 | 669 |
662 (defun tar-subfile-mode (p) | 670 (defun tar-subfile-mode (p) |
663 "Minor mode for editing an element of a tar-file. | 671 "Minor mode for editing an element of a tar-file. |
664 This mode arranges for \"saving\" this buffer to write the data | 672 This mode arranges for \"saving\" this buffer to write the data |
771 tarname | 779 tarname |
772 ")")) | 780 ")")) |
773 (read-only-p (or buffer-read-only view-p)) | 781 (read-only-p (or buffer-read-only view-p)) |
774 (new-buffer-file-name (expand-file-name | 782 (new-buffer-file-name (expand-file-name |
775 ;; `:' is not allowed on Windows | 783 ;; `:' is not allowed on Windows |
776 (concat tarname "!" name))) | 784 (concat tarname "!" |
785 (if (string-match "/" name) | |
786 name | |
787 ;; Make sure `name' contains a / | |
788 ;; so set-auto-mode doesn't try | |
789 ;; to look at `tarname' for hints. | |
790 (concat "./" name))))) | |
777 (buffer (get-file-buffer new-buffer-file-name)) | 791 (buffer (get-file-buffer new-buffer-file-name)) |
778 (just-created nil) | 792 (just-created nil) |
779 undo-list) | 793 undo-list) |
780 (unless buffer | 794 (unless buffer |
781 (setq buffer (generate-new-buffer bufname)) | 795 (setq buffer (generate-new-buffer bufname)) |