Subject: bug#75784: Typo "unreadeable" in print.c; was exposed to Lisp

From: Pip Cet <[email-masked]>
Date: Sat, 25 Jan 2025 10:51:01 +0000

Pip Cet <[email-masked]> writes:

> From 1eb35efa41da5dd00f1c824c6b396c89bf4f0ca8 Mon Sep 17 00:00:00 2001
> From: Pip Cet <[email-masked]>
> Subject: [PATCH] Fix crashes in mapconcat etc. (bug#TBD)
>
> This doesn't attempt to catch all cases in which the mapping function
> modifies the sequence, only those which would cause crashes.
>
> * src/fns.c (mapcar1): Error if we detect seq to have been modified by
> fn.

Additional change required:

diff --git a/src/fns.c b/src/fns.c
index ce09e8c086c..8bfb0cc44d3 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3416,6 +3416,8 @@ mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
 	  if (vals)
 	    vals[i_before] = dummy;
 	}
+      if (i < leni)
+	error ("string modified by mapping function");
     }
   else
     {

This change ensures that vals aren't used uninitialized and bogus
pointers exposed to Lisp.  Usually the memory will be zeroed, I think,
but not always.

Additional change suggested:

@@ -3476,8 +3478,7 @@ DEFUN ("mapconcat", Fmapconcat, Smapconcat, 2, 3, 0,
 	  goto concat;
 	}
     }
-  ptrdiff_t nmapped = mapcar1 (leni, args, function, sequence);
-  eassert (nmapped == leni);
+  leni = mapcar1 (leni, args, function, sequence);
 
  concat: ;
   ptrdiff_t nargs = args_alloc;

The second hunk isn't necessary because mapcar1 will signal an error
rather than returning a smaller value if the list has been truncated,
and will return leni (and leave vals invalid).

This is a special case where removing an eassert is the right thing to
do, IMHO.

If any further complications arise, I'll report a new bug, but so far it
still looks like a reasonably obvious pushable fix to me.  Comment needs
expanding to list the crashable code, and it needs to become an Emacs
crash test when we have those (there's no time pressure there).

Pip