Subject: bug#78590: 31.0.50; print_object calls strout unsafely

From: Eli Zaretskii <[email-masked]>
Date: Mon, 26 May 2025 21:48:18 +0300

> Date: Mon, 26 May 2025 18:00:28 +0000
> From:  Pip Cet via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <[email-masked]>
> 
> Pip Cet <[email-masked]> writes:
> 
> > It's probably not worth it to come up with a complicated fix here: let's
> > just use SAFE_ALLOCA_STRING, and add a comment explaining the reasons
> > (GC, Lisp code modifying the string that is being printed).
> 
> OK for master?

I agree that the current code is buggy because it keeps referencing a
Lisp string's data via a 'char *' pointer while calling a Lisp
function PRINTCHARFUN.  But I wonder whether the best solution is to
copy the string to a C buffer.  E.g., what if the string is very long?
we'd just have two copies of it during the print, which increases
memory pressure.

How about replacing iteration over a C 'char *' buffer with iteration
over the original string (using SREF or string_char_and_length)?  That
is, instead of

	      int len, ch = (string_char_and_length
			     ((const unsigned char *) ptr + i, &len));
use

	      int len, ch = (string_char_and_length
			     (SDATA (string) + i, &len));

where 'string' is the original Lisp string to print?  If this requires
adding an additional argument to strout, to pass the Lisp string,
which will be used only in the last 'else' clause there, that's not
difficult, right?

Thanks.