From aa0c679f484347d20ab6f7c0f75f32f5e360cb89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Sun, 29 Dec 2019 13:51:48 +0100 Subject: [PATCH 1/9] Avoid unbounded growth of cl-random-state components (bug#38753) * lisp/emacs-lisp/cl-extra.el (cl-random): Perform the modulo 2**23 operation before updating the state instead of after. The result is always the same, but it prevents the state from growing into arbitrary large bignums. Patch from Christopher Wellons. --- lisp/emacs-lisp/cl-extra.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)))) From 732dcfc85078dafb4b5983de3cadb7a65329dc47 Mon Sep 17 00:00:00 2001 From: Robert Pluim Date: Sun, 29 Dec 2019 20:08:38 +0100 Subject: [PATCH 2/9] Ignore all color fonts when using XFT * etc/NEWS: Announce change to matching color fonts when using XFT. * src/ftfont.c (ftfont_list) [HAVE_XFT && FC_COLOR]: Query for the color attribute of the matched font, and skip it if it is not FcFalse (Bug#37786). --- etc/NEWS | 8 ++++++++ src/ftfont.c | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index e630bb71fec..c6051c97f5b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -296,6 +296,14 @@ To get the old, less-secure behavior, you can set the *** When run by root, emacsclient no longer connects to non-root sockets. (Instead you can use Tramp methods to run root commands in a non-root Emacs.) +--- +*** 'xft-ignore-color-fonts' now ignores even more color fonts. +There are color fonts that managed to bypass the existing checks, +causing XFT crashes, they are now filtered out. Setting +'xft-ignore-color-conts' to nil removes those checks, which might +require setting 'face-ignored-fonts' to filter out problematic fonts. +Known problematic fonts are "Noto Color Emoji" and "Emoji One". + +++ ** New user option 'what-cursor-show-names'. When non-nil, 'what-cursor-position' will show the name of the character diff --git a/src/ftfont.c b/src/ftfont.c index b8199dc4ba7..5bc048c3003 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -864,6 +864,9 @@ ftfont_list (struct frame *f, Lisp_Object spec) #endif /* FC_CAPABILITY */ #ifdef FC_FONTFORMAT FC_FONTFORMAT, +#endif +#if defined HAVE_XFT && defined FC_COLOR + FC_COLOR, #endif NULL); if (! objset) @@ -904,7 +907,19 @@ ftfont_list (struct frame *f, Lisp_Object spec) for (i = 0; i < fontset->nfont; i++) { Lisp_Object entity; - +#if defined HAVE_XFT && defined FC_COLOR + { + /* Some fonts, notably NotoColorEmoji, have an FC_COLOR value + that's neither FcTrue nor FcFalse, which means FcFontList + returns them even when it shouldn't really do so, so we + need to manually skip them here (Bug#37786). */ + FcBool b; + if (Vxft_ignore_color_fonts + && FcPatternGetBool (fontset->fonts[i], FC_COLOR, 0, &b) + == FcResultMatch && b != FcFalse) + continue; + } +#endif if (spacing >= 0) { int this; From 9ce4207969f61476a78ba9fc3cb1fecdc3702013 Mon Sep 17 00:00:00 2001 From: Robert Pluim Date: Sun, 29 Dec 2019 20:34:20 +0100 Subject: [PATCH 3/9] Revert "Check for GUI frame in ns_color_index_to_rgba" This reverts commit ea84a95bd8d43612b4a424fb93de25a68ac31d05. --- src/nsterm.m | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index 9e036aa1608..fbec816cccd 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2290,24 +2290,19 @@ ns_lisp_to_color (Lisp_Object color, NSColor **col) /* Convert an index into the color table into an RGBA value. Used in xdisp.c:extend_face_to_end_of_line when comparing faces and frame - color values. No-op on non-gui frames. */ + color values. */ unsigned long ns_color_index_to_rgba(int idx, struct frame *f) { - if (FRAME_DISPLAY_INFO (f)) - { - NSColor *col; - col = ns_lookup_indexed_color (idx, f); + NSColor *col; + col = ns_lookup_indexed_color (idx, f); - EmacsCGFloat r, g, b, a; - [col getRed: &r green: &g blue: &b alpha: &a]; + EmacsCGFloat r, g, b, a; + [col getRed: &r green: &g blue: &b alpha: &a]; - return ARGB_TO_ULONG((int)(a*255), - (int)(r*255), (int)(g*255), (int)(b*255)); - } - else - return idx; + return ARGB_TO_ULONG((int)(a*255), + (int)(r*255), (int)(g*255), (int)(b*255)); } void From 81b697d1062efa039b542082b89fc0170b3db42c Mon Sep 17 00:00:00 2001 From: Robert Pluim Date: Sun, 29 Dec 2019 20:41:28 +0100 Subject: [PATCH 4/9] Fix crash under -nw on macOS properly this time * src/dispextern.h (FACE_COLOR_TO_PIXEL): Only use ns_color_index_to_rgba when we're running under the NS gui (Bug#38564). --- src/dispextern.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dispextern.h b/src/dispextern.h index 0615b16d712..4bf9f39cd08 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -123,7 +123,9 @@ typedef HDC Emacs_Pix_Context; #ifdef HAVE_NS #include "nsgui.h" -#define FACE_COLOR_TO_PIXEL(face_color, frame) ns_color_index_to_rgba(face_color, frame) +#define FACE_COLOR_TO_PIXEL(face_color, frame) (FRAME_NS_P (frame) \ + ? ns_color_index_to_rgba (face_color, frame) \ + : face_color) /* Following typedef needed to accommodate the MSDOS port, believe it or not. */ typedef struct ns_display_info Display_Info; typedef Emacs_Pixmap Emacs_Pix_Container; From 4bbfd2b42f73f35da6c5b338239308428809c5f7 Mon Sep 17 00:00:00 2001 From: Robert Pluim Date: Sun, 29 Dec 2019 22:21:48 +0100 Subject: [PATCH 5/9] ; fix previous NEWS entry --- etc/NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index c6051c97f5b..0c055ca682b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -297,10 +297,10 @@ To get the old, less-secure behavior, you can set the (Instead you can use Tramp methods to run root commands in a non-root Emacs.) --- -*** 'xft-ignore-color-fonts' now ignores even more color fonts. +** 'xft-ignore-color-fonts' now ignores even more color fonts. There are color fonts that managed to bypass the existing checks, causing XFT crashes, they are now filtered out. Setting -'xft-ignore-color-conts' to nil removes those checks, which might +'xft-ignore-color-fonts' to nil removes those checks, which might require setting 'face-ignored-fonts' to filter out problematic fonts. Known problematic fonts are "Noto Color Emoji" and "Emoji One". From 219d47893aef0da1dc42f0c5445df68a2abf480a Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sun, 29 Dec 2019 15:41:52 -0800 Subject: [PATCH 6/9] Fixes for makeinfo 4.13 * doc/lispref/customize.texi (Variable Definitions): Fix xref. * doc/lispref/internals.texi (Writing Emacs Primitives) (Module Values): Follow xref with comma. --- doc/lispref/customize.texi | 3 +-- doc/lispref/internals.texi | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index b19feaf977f..a44446b1319 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -431,8 +431,7 @@ the build-time context. This also has the side-effect that the @kindex local@r{, @code{defcustom} keyword} If the @var{value} is @code{t}, mark @var{option} as automatically buffer-local; if the value is @code{permanent}, also set @var{option}s -@code{permanent-local} property to @code{t}. @xref {Creating -Buffer-Local}. +@code{permanent-local} property to @code{t}. @xref{Creating Buffer-Local}. @item :risky @var{value} @kindex risky@r{, @code{defcustom} keyword} diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 1d03cbd085b..36d32ffddab 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -972,7 +972,7 @@ The name of the variable to be used by Lisp programs. The name of the variable in the C sources. @item doc The documentation for the variable, as a C -comment. @xref{Documentation Basics} for more details. +comment. @xref{Documentation Basics}, for more details. @end table By convention, when defining variables of a ``native'' type @@ -1647,7 +1647,7 @@ little-endian magnitude of the return value. The following example uses the GNU Multiprecision Library (GMP) to calculate the next probable prime after a given integer. -@xref{Top,,,gmp} for a general overview of GMP, and @pxref{Integer +@xref{Top,,,gmp}, for a general overview of GMP, and @pxref{Integer Import and Export,,,gmp} for how to convert the @code{magnitude} array to and from GMP @code{mpz_t} values. From 450633f85ae336e8a23241ec3ca5de5d8de8dcdd Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 30 Dec 2019 17:53:52 +0200 Subject: [PATCH 7/9] Fix mini-window resizing under resize-mini-windows = t * src/window.c (grow_mini_window): Fix resizing of mini-window when the echo area is cleared, and the caller asks for the mini-window to have zero lines. (Bug#38791) --- src/window.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/window.c b/src/window.c index c52a8ca2855..1962e07f8d0 100644 --- a/src/window.c +++ b/src/window.c @@ -5229,10 +5229,15 @@ grow_mini_window (struct window *w, int delta) { struct frame *f = XFRAME (w->frame); int old_height = window_body_height (w, true); + int min_height = FRAME_LINE_HEIGHT (f); eassert (MINI_WINDOW_P (w)); - if ((delta != 0) && (old_height + delta >= FRAME_LINE_HEIGHT (f))) + /* Never shrink mini-window to less than its minimum height. */ + if (old_height + delta < min_height) + delta = old_height > min_height ? min_height - old_height : 0; + + if (delta != 0) { Lisp_Object root = FRAME_ROOT_WINDOW (f); struct window *r = XWINDOW (root); From e3ec84fd7d91c9fff756e28d14ce33f7a37ac19f Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 30 Dec 2019 18:00:17 +0200 Subject: [PATCH 8/9] Ensure mini-window is resized to show active minibuffer contents * src/keyboard.c (read_char, command_loop_1): Resize the mini-window after clearing the echo area while minibuffer is active. (Bug#38645) --- src/keyboard.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/keyboard.c b/src/keyboard.c index 4cf1f64b487..cb311efd7e5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1318,6 +1318,11 @@ command_loop_1 (void) message1 (0); safe_run_hooks (Qecho_area_clear_hook); + /* We cleared the echo area, and the minibuffer will now + show, so resize the mini-window in case the minibuffer + needs more or less space than the echo area. */ + resize_mini_window (XWINDOW (minibuf_window), false); + unbind_to (count, Qnil); /* If a C-g came in before, treat it as input now. */ @@ -2989,6 +2994,16 @@ read_char (int commandflag, Lisp_Object map, { safe_run_hooks (Qecho_area_clear_hook); clear_message (1, 0); + /* If we were showing the echo-area message on top of an + active minibuffer, resize the mini-window, since the + minibuffer may need more or less space than the echo area + we've just wiped. */ + if (minibuf_level + && EQ (minibuf_window, echo_area_window) + /* The case where minibuffer-message-timeout is a number + was already handled near the beginning of command_loop_1. */ + && !NUMBERP (Vminibuffer_message_timeout)) + resize_mini_window (XWINDOW (minibuf_window), false); } else if (FUNCTIONP (Vclear_message_function)) clear_message (1, 0); From 59f71d20eade09e6c2ef99fc4d9b99a161bff040 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 30 Dec 2019 18:17:03 +0200 Subject: [PATCH 9/9] Fix tar-mode reading the oldgnu Tar format This makes sure an entry for a long file name will not accidentally appear as a directory, and thus its size will be disregarded, causing corrupted file headers for all the subsequent entries. The original problem happened because the long file name truncated to 99 bytes happened to end in a slash, which tar-mode takes to be the indication of a directory. * lisp/tar-mode.el (tar-header-block-tokenize): Accept an additional argument DISABLE-SLASH; if non-nil, don't set the link-type field of the descriptor to 5 (meaning a directory) just because the name ends in a slash. Use this argument when calling itself recursively, to read the entry of the file with a long name. Set the link-type to 5 if the long name ends in a slash. (Bug#38777) --- lisp/tar-mode.el | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) 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)