Subject: bug#75581: 30.0.93; Crash when copy-sequence on clear-string'ed multibyte strings with text properties

From: Pip Cet <[email-masked]>
Date: Wed, 15 Jan 2025 20:35:07 +0000

"Stefan Kangas" <[email-masked]> writes:

> Andreas Schwab <[email-masked]> writes:
>
>> On Jan 15 2025, Kanakana wrote:
>>
>>> I don't know. Are text properties expected to handle string length
>>> change via clear-string?
>>
>> clear-string should probably remove any text properties.
>
> Agreed.  This patch fixes the crash for me:
>
> diff --git a/src/fns.c b/src/fns.c
> index 191154c651a..c48cdf879e4 100644
> --- a/src/fns.c
> +++ b/src/fns.c
> @@ -3315,6 +3315,8 @@ DEFUN ("clear-string", Fclear_string, Sclear_string,
>  {
>    CHECK_STRING (string);
>    ptrdiff_t len = SBYTES (string);
> +  Fset_text_properties (make_fixnum (0), make_fixnum (SCHARS (string)),
> +			Qnil, string);
>    if (len != 0 || STRING_MULTIBYTE (string))
>      {
>        CHECK_IMPURE (string, XSTRING (string));

Looks good to me.  However, on the scratch/no-purespace branch, we need
to ensure that this function cannot be called on the empty multibyte
string, turning it into a second empty unibyte string!  I'll push a fix
to that branch in a bit.

However, if this function is meant to clear a string from memory
to prevent leaving confidential data in memory, that won't work with
MPS.  (I suppose it's reasonably clear that no protection whatsoever
applies to string properties?)

The problem is MPS allocates string data in a "copying" pool, so several
copies of the string will usually be present.

alloc.c string compaction may also result in recently-used short strings
remaining in memory, IIUC, but only if an alloc.c GC cycle happens
between string creation and the clear-string call.  (But if it does
happen, it's very likely that a copy of the string is created!)

How important is this feature?  What we have now is better that nothing,
but if people start relying on it in any way, that's worse than nothing.
A stern warning in the docstring may help reduce the problem.

Pip