diff options
| author | Pip Cet | 2025-06-28 09:33:01 +0000 |
|---|---|---|
| committer | Pip Cet | 2025-06-28 10:46:08 +0000 |
| commit | 6b19eb53c5048cfec1f3601afb44f94ebbb9d138 (patch) | |
| tree | 201e5d624f38626ef24e26fb243b644656e585b7 | |
| parent | c64b2bf113eaa2044c24860d0610c3b8ebd7e742 (diff) | |
| download | emacs-6b19eb53c5048cfec1f3601afb44f94ebbb9d138.tar.gz emacs-6b19eb53c5048cfec1f3601afb44f94ebbb9d138.zip | |
Avoid extra output in Vprin1_to_string_buffer (bug#78842)
print_error_message can throw after producing some output, so use
unwind-protect to ensure prin1-to-string-buffer is cleared.
* src/print.c (erase_prin1_to_string_buffer): New.
(Ferror_message_string): Use it to catch errors thrown in
'print_error_message'.
* test/src/print-tests.el (error-message-string-circular): Expand
test.
| -rw-r--r-- | src/print.c | 23 | ||||
| -rw-r--r-- | test/src/print-tests.el | 4 |
2 files changed, 17 insertions, 10 deletions
diff --git a/src/print.c b/src/print.c index b6ee89478c7..138a21f18ab 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1023,6 +1023,14 @@ debug_format (const char *fmt, Lisp_Object arg) | |||
| 1023 | } | 1023 | } |
| 1024 | 1024 | ||
| 1025 | 1025 | ||
| 1026 | /* Erase the Vprin1_to_string_buffer, potentially switching to it. */ | ||
| 1027 | static void | ||
| 1028 | erase_prin1_to_string_buffer (void) | ||
| 1029 | { | ||
| 1030 | set_buffer_internal (XBUFFER (Vprin1_to_string_buffer)); | ||
| 1031 | Ferase_buffer (); | ||
| 1032 | } | ||
| 1033 | |||
| 1026 | DEFUN ("error-message-string", Ferror_message_string, Serror_message_string, | 1034 | DEFUN ("error-message-string", Ferror_message_string, Serror_message_string, |
| 1027 | 1, 1, 0, | 1035 | 1, 1, 0, |
| 1028 | doc: /* Convert an error value (ERROR-SYMBOL . DATA) to an error message. | 1036 | doc: /* Convert an error value (ERROR-SYMBOL . DATA) to an error message. |
| @@ -1030,9 +1038,6 @@ See Info anchor `(elisp)Definition of signal' for some details on how this | |||
| 1030 | error message is constructed. */) | 1038 | error message is constructed. */) |
| 1031 | (Lisp_Object obj) | 1039 | (Lisp_Object obj) |
| 1032 | { | 1040 | { |
| 1033 | struct buffer *old = current_buffer; | ||
| 1034 | Lisp_Object value; | ||
| 1035 | |||
| 1036 | /* If OBJ is (error STRING), just return STRING. | 1041 | /* If OBJ is (error STRING), just return STRING. |
| 1037 | That is not only faster, it also avoids the need to allocate | 1042 | That is not only faster, it also avoids the need to allocate |
| 1038 | space here when the error is due to memory full. */ | 1043 | space here when the error is due to memory full. */ |
| @@ -1042,15 +1047,15 @@ error message is constructed. */) | |||
| 1042 | && NILP (XCDR (XCDR (obj)))) | 1047 | && NILP (XCDR (XCDR (obj)))) |
| 1043 | return XCAR (XCDR (obj)); | 1048 | return XCAR (XCDR (obj)); |
| 1044 | 1049 | ||
| 1050 | /* print_error_message can throw after producing some output, in which | ||
| 1051 | case we need to ensure the buffer is cleared again (bug#78842). */ | ||
| 1052 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 1053 | record_unwind_current_buffer (); | ||
| 1054 | record_unwind_protect_void (erase_prin1_to_string_buffer); | ||
| 1045 | print_error_message (obj, Vprin1_to_string_buffer, 0, Qnil); | 1055 | print_error_message (obj, Vprin1_to_string_buffer, 0, Qnil); |
| 1046 | 1056 | ||
| 1047 | set_buffer_internal (XBUFFER (Vprin1_to_string_buffer)); | 1057 | set_buffer_internal (XBUFFER (Vprin1_to_string_buffer)); |
| 1048 | value = Fbuffer_string (); | 1058 | return unbind_to (count, Fbuffer_string ()); |
| 1049 | |||
| 1050 | Ferase_buffer (); | ||
| 1051 | set_buffer_internal (old); | ||
| 1052 | |||
| 1053 | return value; | ||
| 1054 | } | 1059 | } |
| 1055 | 1060 | ||
| 1056 | /* Print an error message for the error DATA onto Lisp output stream | 1061 | /* Print an error message for the error DATA onto Lisp output stream |
diff --git a/test/src/print-tests.el b/test/src/print-tests.el index 036248fd091..ce8c095d496 100644 --- a/test/src/print-tests.el +++ b/test/src/print-tests.el | |||
| @@ -356,7 +356,9 @@ otherwise, use a different charset." | |||
| 356 | (print-tests--deftest error-message-string-circular () | 356 | (print-tests--deftest error-message-string-circular () |
| 357 | (let ((err (list 'error))) | 357 | (let ((err (list 'error))) |
| 358 | (setcdr err err) | 358 | (setcdr err err) |
| 359 | (should-error (error-message-string err) :type 'circular-list))) | 359 | (should-error (error-message-string err) :type 'circular-list) |
| 360 | ;; check that prin1-to-string-buffer is cleared (bug#78842) | ||
| 361 | (should (equal "37.0" (prin1-to-string 37.0))))) | ||
| 360 | 362 | ||
| 361 | (print-tests--deftest print-hash-table-test () | 363 | (print-tests--deftest print-hash-table-test () |
| 362 | (should | 364 | (should |