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

From: Pip Cet <[email-masked]>
Date: Fri, 24 Jan 2025 14:15:06 +0000

Pip Cet <[email-masked]> writes:

> "Stefan Kangas" <[email-masked]> writes:
>
> I'm sorry: why both names?  The new name should be permanent, unless we
> decide to move to a different name entirely to get rid of the typo (this
> is what happened with kdb-macro-redisplay, IIRC).
>
>> Would you like to suggest a patch?
>
> diff --git a/src/print.c b/src/print.c

Here's a better patch.  While this goes overboard and fixes the case
that Vprint_variable_mapping has become invalid, I'm not sure this can
happen: Fassq can quit, but the Lisp backtrace won't expose its
arguments to the debugger, it seems.  I'd like to err on the side of
caution and double-check that this mapping is still valid in case
someone somehow exposes it to Lisp.

Note that specbind currently insists on a BARE_SYMBOL.  We'll have to
check all callers to make sure they never pass a symbol-with-position!

Tested only very briefly.

>From 879714122b1de7852be898a7940ed85aefde6e2e Mon Sep 17 00:00:00 2001
From: Pip Cet <[email-masked]>
Subject: [PATCH] Fix typo (and bugs) in prin1's overrides code (bug#75754)

Vprint_variable_mapping may have been exposed to Lisp via the
backtrace if there was a previous quit in the Fassq call, requiring us
to check it still has the intended format.

* src/print.c (print_create_variable_mapping): Add correct spelling
"unreadable-function" as an alternative to "unreadeable-function".
(print_bind_overrides): Preserve original argument for error case. Use
FOR_EACH_TAIL, fixing infloop.  Warn about obsolete symbol.  Guard
against invalid Vprint_variable_mapping.
---
 src/print.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/print.c b/src/print.c
index 43698f309b1..0da2baa6e09 100644
--- a/src/print.c
+++ b/src/print.c
@@ -676,6 +676,8 @@ print_create_variable_mapping (void)
 	   intern ("print-escape-multibyte"), Qnil),
     list3 (intern ("charset-text-property"),
 	   intern ("print-charset-text-property"), Qnil),
+    list3 (intern ("unreadable-function"),
+	   intern ("print-unreadable-function"), Qnil),
     list3 (intern ("unreadeable-function"),
 	   intern ("print-unreadable-function"), Qnil),
     list3 (intern ("gensym"), intern ("print-gensym"), Qnil),
@@ -698,11 +700,10 @@ print_bind_overrides (Lisp_Object overrides)
 
   if (EQ (overrides, Qt))
     print_bind_all_defaults ();
-  else if (!CONSP (overrides))
-    xsignal (Qwrong_type_argument, Qconsp);
   else
     {
-      while (!NILP (overrides))
+      Lisp_Object original_overrides = overrides;
+      FOR_EACH_TAIL (overrides)
 	{
 	  Lisp_Object setting = XCAR (overrides);
 	  if (EQ (setting, Qt))
@@ -714,15 +715,23 @@ print_bind_overrides (Lisp_Object overrides)
 	      Lisp_Object key = XCAR (setting),
 		value = XCDR (setting);
 	      Lisp_Object map = Fassq (key, Vprint_variable_mapping);
+	      static bool warned;
+	      if (!warned && SYMBOLP (key) &&
+		  strcmp (SSDATA (SYMBOL_NAME (key)),
+			  "unreadeable-function") == 0)
+		{
+		  warned = true;
+		  add_to_log ("Obsolete symbol `unreadeable-function' used.  Use `unreadable-function' instead.");
+		}
 	      if (NILP (map))
 		xsignal2 (Qwrong_type_argument, Qsymbolp, map);
-	      specbind (XCAR (XCDR (map)), value);
+	      Lisp_Object bare_symbol =
+		maybe_remove_pos_from_symbol (Fcar (XCDR (map)));
+	      CHECK_SYMBOL (bare_symbol);
+	      specbind (bare_symbol, value);
 	    }
-
-	  if (!NILP (XCDR (overrides)) && !CONSP (XCDR (overrides)))
-	    xsignal (Qwrong_type_argument, Qconsp);
-	  overrides = XCDR (overrides);
 	}
+      CHECK_LIST_END (overrides, original_overrides);
     }
 }
 
-- 
2.47.1