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))