diff options
| author | Lars Ingebrigtsen | 2022-07-28 12:23:53 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-07-28 12:24:03 +0200 |
| commit | 4895ca16f76aa0ec044212a2b96ef8646cf4d0ed (patch) | |
| tree | 31eb004564adcdaaa0df8ee912a323444b456e18 | |
| parent | 22a5f022344af8c0c0a9eddc2ac5ad36392d0cef (diff) | |
| download | emacs-4895ca16f76aa0ec044212a2b96ef8646cf4d0ed.tar.gz emacs-4895ca16f76aa0ec044212a2b96ef8646cf4d0ed.zip | |
Ensure that we don't call print-unreadable-function from " prin1"
* src/print.c (PRINTPREPARE): Bind the current buffer so that we
can retrieve it later.
(print_vectorlike): Use it (bug#56773).
(syms_of_print): New internal `print--unreadable-callback-buffer'
variable.
| -rw-r--r-- | src/print.c | 19 | ||||
| -rw-r--r-- | test/lisp/subr-tests.el | 10 | ||||
| -rw-r--r-- | test/src/print-tests.el | 1 |
3 files changed, 29 insertions, 1 deletions
diff --git a/src/print.c b/src/print.c index 384a639b317..48c945d08a0 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -105,6 +105,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1; | |||
| 105 | = !NILP (BVAR (current_buffer, enable_multibyte_characters)); \ | 105 | = !NILP (BVAR (current_buffer, enable_multibyte_characters)); \ |
| 106 | Lisp_Object original = printcharfun; \ | 106 | Lisp_Object original = printcharfun; \ |
| 107 | record_unwind_current_buffer (); \ | 107 | record_unwind_current_buffer (); \ |
| 108 | specbind(Qprint__unreadable_callback_buffer, Fcurrent_buffer ()); \ | ||
| 108 | if (NILP (printcharfun)) printcharfun = Qt; \ | 109 | if (NILP (printcharfun)) printcharfun = Qt; \ |
| 109 | if (BUFFERP (printcharfun)) \ | 110 | if (BUFFERP (printcharfun)) \ |
| 110 | { \ | 111 | { \ |
| @@ -1655,6 +1656,17 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | |||
| 1655 | infinite recursion in the function called. */ | 1656 | infinite recursion in the function called. */ |
| 1656 | Lisp_Object func = Vprint_unreadable_function; | 1657 | Lisp_Object func = Vprint_unreadable_function; |
| 1657 | specbind (Qprint_unreadable_function, Qnil); | 1658 | specbind (Qprint_unreadable_function, Qnil); |
| 1659 | |||
| 1660 | /* If we're being called from `prin1-to-string' or the like, | ||
| 1661 | we're now in the secret " prin1" buffer. This can lead to | ||
| 1662 | problems if, for instance, the callback function switches a | ||
| 1663 | window to this buffer -- this will make Emacs segfault. */ | ||
| 1664 | if (!NILP (Vprint__unreadable_callback_buffer) | ||
| 1665 | && Fbuffer_live_p (Vprint__unreadable_callback_buffer)) | ||
| 1666 | { | ||
| 1667 | record_unwind_current_buffer (); | ||
| 1668 | set_buffer_internal (XBUFFER (Vprint__unreadable_callback_buffer)); | ||
| 1669 | } | ||
| 1658 | Lisp_Object result = CALLN (Ffuncall, func, obj, | 1670 | Lisp_Object result = CALLN (Ffuncall, func, obj, |
| 1659 | escapeflag? Qt: Qnil); | 1671 | escapeflag? Qt: Qnil); |
| 1660 | unbind_to (count, Qnil); | 1672 | unbind_to (count, Qnil); |
| @@ -2913,6 +2925,13 @@ be printed. */); | |||
| 2913 | Vprint_unreadable_function = Qnil; | 2925 | Vprint_unreadable_function = Qnil; |
| 2914 | DEFSYM (Qprint_unreadable_function, "print-unreadable-function"); | 2926 | DEFSYM (Qprint_unreadable_function, "print-unreadable-function"); |
| 2915 | 2927 | ||
| 2928 | DEFVAR_LISP ("print--unreadable-callback-buffer", | ||
| 2929 | Vprint__unreadable_callback_buffer, | ||
| 2930 | doc: /* Dynamically bound to indicate current buffer. */); | ||
| 2931 | Vprint__unreadable_callback_buffer = Qnil; | ||
| 2932 | DEFSYM (Qprint__unreadable_callback_buffer, | ||
| 2933 | "print--unreadable-callback-buffer"); | ||
| 2934 | |||
| 2916 | defsubr (&Sflush_standard_output); | 2935 | defsubr (&Sflush_standard_output); |
| 2917 | 2936 | ||
| 2918 | /* Initialized in print_create_variable_mapping. */ | 2937 | /* Initialized in print_create_variable_mapping. */ |
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 20f81d1ddc5..1d85631a4b8 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el | |||
| @@ -1122,5 +1122,15 @@ final or penultimate step during initialization.")) | |||
| 1122 | (should (equal (butlast l n) | 1122 | (should (equal (butlast l n) |
| 1123 | (subr-tests--butlast-ref l n)))))) | 1123 | (subr-tests--butlast-ref l n)))))) |
| 1124 | 1124 | ||
| 1125 | (ert-deftest test-print-unreadable-function-buffer () | ||
| 1126 | (with-temp-buffer | ||
| 1127 | (let ((current (current-buffer)) | ||
| 1128 | callback-buffer) | ||
| 1129 | (let ((print-unreadable-function | ||
| 1130 | (lambda (_object _escape) | ||
| 1131 | (setq callback-buffer (current-buffer))))) | ||
| 1132 | (prin1-to-string (make-marker))) | ||
| 1133 | (should (eq current callback-buffer))))) | ||
| 1134 | |||
| 1125 | (provide 'subr-tests) | 1135 | (provide 'subr-tests) |
| 1126 | ;;; subr-tests.el ends here | 1136 | ;;; subr-tests.el ends here |
diff --git a/test/src/print-tests.el b/test/src/print-tests.el index f818b4d4715..91187d9f45c 100644 --- a/test/src/print-tests.el +++ b/test/src/print-tests.el | |||
| @@ -529,6 +529,5 @@ otherwise, use a different charset." | |||
| 529 | (should (equal (% (- (length numbers) loopback-index) loop) | 529 | (should (equal (% (- (length numbers) loopback-index) loop) |
| 530 | 0))))))))))) | 530 | 0))))))))))) |
| 531 | 531 | ||
| 532 | |||
| 533 | (provide 'print-tests) | 532 | (provide 'print-tests) |
| 534 | ;;; print-tests.el ends here | 533 | ;;; print-tests.el ends here |