Subject: Re: bug#75593: 31.0.50; Faulty macro kills Emacs

From: Eli Zaretskii <[email-masked]>
Date: Thu, 16 Jan 2025 08:50:37 +0200

> Date: Wed, 15 Jan 2025 22:20:42 +0000
> From: Pip Cet <[email-masked]>
> Cc: Eli Zaretskii <[email-masked]>, Alexander Prähauser <[email-masked]>, [email-masked]
> 
> --- a/src/eval.c
> +++ b/src/eval.c
> @@ -2446,8 +2446,11 @@ DEFUN ("eval", Feval, Seval, 1, 2, 0,
>    (Lisp_Object form, Lisp_Object lexical)
>  {
>    specpdl_ref count = SPECPDL_INDEX ();
> -  specbind (Qinternal_interpreter_environment,
> -	    CONSP (lexical) || NILP (lexical) ? lexical : list_of_t);
> +  if (CONSP (lexical) || NILP (lexical))
> +    Flength (lexical);
> +  else
> +    lexical = list_of_t;
> +  specbind (Qinternal_interpreter_environment, lexical);
>    return unbind_to (count, eval_sub (form));
>  }

Isn't there a cheaper way of verifying LEXICAL is a list, not a cons
cell?

How about calling Flength only "#ifdef ENABLE_CHECKING", and otherwise
just verifying that LEXICAL is a list?  After all, passing a circular
list to this function means some Lisp program shoots itself in the
foot, so we could tell "don't do that", like in other cases when Emacs
gives Lisp programmers enough rope to hang themselves.

IOW, can we prevent crashes in a way that is cheap in production
builds, since 'eval' is quite a hotspot?