aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPip Cet2025-06-28 09:33:01 +0000
committerPip Cet2025-06-28 10:46:08 +0000
commit6b19eb53c5048cfec1f3601afb44f94ebbb9d138 (patch)
tree201e5d624f38626ef24e26fb243b644656e585b7 /src
parentc64b2bf113eaa2044c24860d0610c3b8ebd7e742 (diff)
downloademacs-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.
Diffstat (limited to 'src')
-rw-r--r--src/print.c23
1 files changed, 14 insertions, 9 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. */
1027static void
1028erase_prin1_to_string_buffer (void)
1029{
1030 set_buffer_internal (XBUFFER (Vprin1_to_string_buffer));
1031 Ferase_buffer ();
1032}
1033
1026DEFUN ("error-message-string", Ferror_message_string, Serror_message_string, 1034DEFUN ("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
1030error message is constructed. */) 1038error 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