Fix unsafe SDATA usage in print.c (bug#78590)

* src/print.c (print_string_1): Renamed from 'print_string', with an
extra argument to disable nonascii escaping.
(print_string): New function.
(print_object): Use 'print_string_1', not 'strout'.
This commit is contained in:
Pip Cet 2025-05-28 14:11:07 +00:00
parent 295f73d23d
commit d14fc6b75f
2 changed files with 28 additions and 4 deletions

View file

@ -469,18 +469,18 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
because printing one char can relocate. */
static void
print_string (Lisp_Object string, Lisp_Object printcharfun)
print_string_1 (Lisp_Object string, Lisp_Object printcharfun, bool escape_nonascii)
{
if (EQ (printcharfun, Qt) || NILP (printcharfun))
{
ptrdiff_t chars;
if (print_escape_nonascii)
if (escape_nonascii)
string = string_escape_byte8 (string);
if (STRING_MULTIBYTE (string))
chars = SCHARS (string);
else if (! print_escape_nonascii
else if (! escape_nonascii
&& (EQ (printcharfun, Qt)
? ! NILP (BVAR (&buffer_defaults, enable_multibyte_characters))
: ! NILP (BVAR (current_buffer, enable_multibyte_characters))))
@ -543,6 +543,12 @@ print_string (Lisp_Object string, Lisp_Object printcharfun)
}
}
}
static void
print_string (Lisp_Object string, Lisp_Object printcharfun)
{
print_string_1 (string, printcharfun, print_escape_nonascii);
}
DEFUN ("write-char", Fwrite_char, Swrite_char, 1, 2, 0,
doc: /* Output character CHARACTER to stream PRINTCHARFUN.
@ -2282,7 +2288,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
}
else if (STRINGP (num))
{
strout (SSDATA (num), SCHARS (num), SBYTES (num), printcharfun);
print_string_1 (num, printcharfun, false);
goto next_obj;
}
}

View file

@ -540,5 +540,23 @@ otherwise, use a different charset."
(should (eq callback-buffer buffer))
(should (equal str "tata"))))
(ert-deftest test-print-number-realloc ()
;; Test for bug#78590. Note that this may in rare cases crash unfixed
;; Emacs versions.
(let ((print-circle t)
(print-number-table (make-hash-table))
(print-continuous-numbering t)
(str "yy")
(outstr ""))
(garbage-collect)
(ignore (make-string 100 ?a))
(puthash str (make-string 3 ?x) print-number-table)
(prin1 str
(lambda (c)
(setq outstr (concat outstr (string c)))
(garbage-collect)
(ignore (make-string 100 ?b))))
(should (equal outstr "xxx"))))
(provide 'print-tests)
;;; print-tests.el ends here