Package: emacs;
Reported by: Alan Mackenzie <acm <at> muc.de>
Date: Fri, 1 Oct 2021 17:12:02 UTC
Severity: normal
Done: João Távora <joaotavora <at> gmail.com>
Bug is archived. No further changes may be made.
Message #118 received at 50946 <at> debbugs.gnu.org (full text, mbox):
From: João Távora <joaotavora <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 50946 <at> debbugs.gnu.org Subject: Re: insert-file-contents can corrupt buffers. [Was: bug#50946: Emacs-28: Inadequate coding in hack-elisp-shorthands] Date: Sun, 03 Oct 2021 19:59:24 +0100
Eli Zaretskii <eliz <at> gnu.org> writes: >> From: João Távora <joaotavora <at> gmail.com> >> Cc: 50946 <at> debbugs.gnu.org >> Date: Sun, 03 Oct 2021 18:05:33 +0100 > Note that previously, the shorthand searching and application was > effectively turned off until very late into the loadup procedure. But > now, we enable it as soon as files.el is loaded, which is way > earlier. Somewhere there is the reason for the problem. Yes, I agree, this makes sense. > So I think, instead of the fboundp test, introduce a variable, > say inhibit-shorthands, set it to t at the beginning of loadup, then > reset to nil after shorthands.el has been loaded. At this point, I think that's slightly worse than introducing hack-read-symbol-shorthands-function... or introducing a hook as I had before. Given you dislike hooks, the patch with hack-read-symbol-shorthands-function is below. Looks good? João commit d4416d7f2083bd55984193b94241edb76bb2879c Author: João Távora <joaotavora <at> gmail.com> Date: Sun Oct 3 16:05:40 2021 +0100 Simplify hack-read-symbol-shorthands again (bug#50946) * lisp/loadup.el (load-source-file-function): Don't set twice. * lisp/shorthands.el (hack-read-symbol-shorthands): Simplify. (load-with-shorthands-and-code-conversion): Remove. * lisp/international/mule.el (load-with-code-conversion): Call hack-read-symbol-shorthands-function. Set up shorthands. (hack-read-symbol-shorthands-function): New variable diff --git a/lisp/international/mule.el b/lisp/international/mule.el index 2a855b5673..d00e39d228 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -294,6 +294,9 @@ define-charset (apply 'define-charset-internal name (mapcar 'cdr attrs)))) +(defvar hack-read-symbol-shorthands-function nil + "Holds function to compute `read-symbol-shorthands'.") + (defun load-with-code-conversion (fullname file &optional noerror nomessage) "Execute a file of Lisp code named FILE whose absolute name is FULLNAME. The file contents are decoded before evaluation if necessary. @@ -319,7 +322,8 @@ load-with-code-conversion (let ((load-true-file-name fullname) (load-file-name fullname) (set-auto-coding-for-load t) - (inhibit-file-name-operation nil)) + (inhibit-file-name-operation nil) + shorthands) (with-current-buffer buffer ;; So that we don't get completely screwed if the ;; file is encoded in some complicated character set, @@ -328,6 +332,12 @@ load-with-code-conversion ;; Don't let deactivate-mark remain set. (let (deactivate-mark) (insert-file-contents fullname)) + (setq shorthands + ;; We need this indirection because hacking local + ;; variables in too early seems to have cause recursive + ;; load loops (bug#50946). + (and hack-read-symbol-shorthands-function + (funcall hack-read-symbol-shorthands-function))) ;; If the loaded file was inserted with no-conversion or ;; raw-text coding system, make the buffer unibyte. ;; Otherwise, eval-buffer might try to interpret random @@ -338,11 +348,13 @@ load-with-code-conversion (set-buffer-multibyte nil)) ;; Make `kill-buffer' quiet. (set-buffer-modified-p nil)) - ;; Have the original buffer current while we eval. - (eval-buffer buffer nil - ;; This is compatible with what `load' does. - (if dump-mode file fullname) - nil t)) + ;; Have the original buffer current while we eval, + ;; but consider shorthands of the eval'ed one. + (let ((read-symbol-shorthands shorthands)) + (eval-buffer buffer nil + ;; This is compatible with what `load' does. + (if dump-mode file fullname) + nil t))) (let (kill-buffer-hook kill-buffer-query-functions) (kill-buffer buffer))) (do-after-load-evaluation fullname) diff --git a/lisp/loadup.el b/lisp/loadup.el index 3fb6b81328..3a55d2c805 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -355,7 +355,6 @@ (load "paren") (load "shorthands") -(setq load-source-file-function #'load-with-shorthands-and-code-conversion) (load "emacs-lisp/eldoc") (load "cus-start") ;Late to reduce customize-rogue (needs loaddefs.el anyway) diff --git a/lisp/shorthands.el b/lisp/shorthands.el index c31ef3d216..40a960ff7d 100644 --- a/lisp/shorthands.el +++ b/lisp/shorthands.el @@ -28,35 +28,15 @@ (require 'files) (eval-when-compile (require 'cl-lib)) -(defun hack-read-symbol-shorthands (fullname) - "Return value of `read-symbol-shorthands' file-local variable in FULLNAME. -FULLNAME is the absolute file name of an Elisp .el file which -potentially specifies a file-local value for -`read-symbol-shorthands'. The Elisp code in FULLNAME isn't read -or evaluated in any way, except for extraction of the -buffer-local value of `read-symbol-shorthands'." - (let* ((size (nth 7 (file-attributes fullname))) - (from (max 0 (- size 3000))) - (to size)) - (with-temp-buffer - (while (and (< (buffer-size) 3000) (>= from 0)) - (insert-file-contents fullname nil from to) - (setq to from - from (cond - ((= from 0) -1) - (t (max 0 (- from 100)))))) - ;; FIXME: relies on the `hack-local-variables--find-variables' - ;; detail of files.el. That function should be exported, - ;; possibly be refactored into two parts, since we're only - ;; interested in basic "Local Variables" parsing. - (alist-get 'read-symbol-shorthands (hack-local-variables--find-variables))))) - -(defun load-with-shorthands-and-code-conversion (fullname file noerror nomessage) - "Like `load-with-code-conversion', but also consider Elisp shorthands. -This function uses shorthands defined in the file FULLNAME's local -value of `read-symbol-shorthands', when it processes that file's Elisp code." - (let ((read-symbol-shorthands (hack-read-symbol-shorthands fullname))) - (load-with-code-conversion fullname file noerror nomessage))) +(defun hack-read-symbol-shorthands () + "Compute `read-symbol-shorthands' from Local Variables section." + ;; FIXME: relies on the `hack-local-variables--find-variables' + ;; detail of files.el. That function should be exported, + ;; possibly be refactored into two parts, since we're only + ;; interested in basic "Local Variables" parsing. + (alist-get 'read-symbol-shorthands (hack-local-variables--find-variables))) + +(setq hack-read-symbol-shorthands-function #'hack-read-symbol-shorthands) ;; FIXME: move this all to progmodes/elisp-mode.el? OTOH it'd make
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.