summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorGlenn Morris <rgm@gnu.org>2019-12-30 09:12:25 -0800
committerGlenn Morris <rgm@gnu.org>2019-12-30 09:12:25 -0800
commit90083b7d78df1b8a054f3028cc9eb8c55a632b1e (patch)
tree458355c729fe23f2f3ca5788fc374e36c9935116 /lisp
parent00c9308ae86dbc2ace7e0154586be84f17036a2b (diff)
parent59f71d20eade09e6c2ef99fc4d9b99a161bff040 (diff)
downloademacs-90083b7d78df1b8a054f3028cc9eb8c55a632b1e.tar.gz
emacs-90083b7d78df1b8a054f3028cc9eb8c55a632b1e.tar.bz2
emacs-90083b7d78df1b8a054f3028cc9eb8c55a632b1e.zip
Merge from origin/emacs-27
59f71d20ea (origin/emacs-27) Fix tar-mode reading the oldgnu Tar format e3ec84fd7d Ensure mini-window is resized to show active minibuffer co... 450633f85a Fix mini-window resizing under resize-mini-windows = t 219d47893a (emacs-27) Fixes for makeinfo 4.13 4bbfd2b42f ; fix previous NEWS entry 81b697d106 Fix crash under -nw on macOS properly this time 9ce4207969 Revert "Check for GUI frame in ns_color_index_to_rgba" 732dcfc850 Ignore all color fonts when using XFT aa0c679f48 Avoid unbounded growth of cl-random-state components (bug#... # Conflicts: # etc/NEWS # src/nsterm.m
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emacs-lisp/cl-extra.el2
-rw-r--r--lisp/tar-mode.el31
2 files changed, 26 insertions, 7 deletions
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index 7e9d8fe870b..2e0b37c14de 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -469,7 +469,7 @@ Optional second arg STATE is a random-state object."
(while (< (setq i (1+ i)) 200) (cl-random 2 state))))
(let* ((i (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-i state)))
(j (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-j state)))
- (n (logand 8388607 (aset vec i (- (aref vec i) (aref vec j))))))
+ (n (aset vec i (logand 8388607 (- (aref vec i) (aref vec j))))))
(if (integerp lim)
(if (<= lim 512) (% n lim)
(if (> lim 8388607) (setq n (+ (ash n 9) (cl-random 512 state))))
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el
index 569b01f978b..d3ad5830cf5 100644
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -223,10 +223,14 @@ Preserve the modified states of the buffers and set `buffer-swapped-with'."
"Round S up to the next multiple of 512."
(ash (ash (+ s 511) -9) 9))
-(defun tar-header-block-tokenize (pos coding)
+(defun tar-header-block-tokenize (pos coding &optional disable-slash)
"Return a `tar-header' structure.
This is a list of name, mode, uid, gid, size,
-write-date, checksum, link-type, and link-name."
+write-date, checksum, link-type, and link-name.
+CODING is our best guess for decoding non-ASCII file names.
+DISABLE-SLASH, if non-nil, means don't decide an entry is a directory
+based on the trailing slash, only based on the \"link-type\" field
+of the file header. This is used for \"old GNU\" Tar format."
(if (> (+ pos 512) (point-max)) (error "Malformed Tar header"))
(cl-assert (zerop (mod (- pos (point-min)) 512)))
(cl-assert (not enable-multibyte-characters))
@@ -272,7 +276,7 @@ write-date, checksum, link-type, and link-name."
(decode-coding-string name coding)
linkname
(decode-coding-string linkname coding))
- (if (and (null link-p) (string-match "/\\'" name))
+ (if (and (null link-p) (null disable-slash) (string-match "/\\'" name))
(setq link-p 5)) ; directory
(if (and (equal name "././@LongLink")
@@ -283,12 +287,23 @@ write-date, checksum, link-type, and link-name."
;; This is a GNU Tar long-file-name header.
(let* ((size (tar-parse-octal-integer
string tar-size-offset tar-time-offset))
- ;; -1 so as to strip the terminating 0 byte.
+ ;; The long name is in the next 512-byte block.
+ ;; We've already moved POS there, when we computed
+ ;; STRING above.
(name (decode-coding-string
+ ;; -1 so as to strip the terminating 0 byte.
(buffer-substring pos (+ pos size -1)) coding))
+ ;; Tokenize the header of the _real_ file entry,
+ ;; which is further 512 bytes into the archive.
(descriptor (tar-header-block-tokenize
- (+ pos (tar-roundup-512 size))
- coding)))
+ (+ pos (tar-roundup-512 size)) coding
+ ;; Don't intuit directories from
+ ;; the trailing slash, because the
+ ;; truncated name might by chance end
+ ;; in a slash.
+ 'ignore-trailing-slash)))
+ ;; Fix the descriptor of the real file entry by using
+ ;; the information from the long name entry.
(cond
((eq link-p (- ?L ?0)) ;GNUTYPE_LONGNAME.
(setf (tar-header-name descriptor) name))
@@ -296,6 +311,10 @@ write-date, checksum, link-type, and link-name."
(setf (tar-header-link-name descriptor) name))
(t
(message "Unrecognized GNU Tar @LongLink format")))
+ ;; Fix the "link-type" attribute, based on the long name.
+ (if (and (null (tar-header-link-type descriptor))
+ (string-match "/\\'" name))
+ (setf (tar-header-link-type descriptor) 5)) ; directory
(setf (tar-header-header-start descriptor)
(copy-marker (- pos 512) t))
descriptor)