• Paul Eggert's avatar
    Fix core dump in substitute-object-in-subtree · 083940a9
    Paul Eggert authored
    Without this fix, (substitute-object-in-subtree #0=(#0# 'a) 'a)
    would dump core, since the C code would recurse indefinitely through
    the infinite structure.  This patch adds an argument to the function,
    and renames it to lread--substitute-object-in-subtree as the function
    is not general-purpose and should not be relied on by outside code.
    See Bug#23660.
    * src/intervals.c (traverse_intervals_noorder): ARG is now void *,
    not Lisp_Object, so that callers need not cons unnecessarily.
    All callers changed.  Also, remove related #if-0 code that was
    “temporary” in the early 1990s and has not been compilable for
    some time.
    * src/lread.c (struct subst): New type, for substitution closure data.
    (seen_list): Remove this static var, as this info is now part of
    struct subst.  All uses removed.
    (Flread__substitute_object_in_subtree): Rename from
    Fsubstitute_object_in_subtree, and give it a 3rd arg so that it
    doesn’t dump core when called from the top level with an
    already-cyclic structure.  All callers changed.
    (SUBSTITUTE): Remove.  All callers expanded and then simplified.
    (substitute_object_recurse): Take a single argument SUBST rather
    than a pair OBJECT and PLACEHOLDER, so that its address can be
    passed around as part of a closure; this avoids the need for an
    AUTO_CONS call.  All callers changed.  If the COMPLETED component
    is t, treat every subobject as potentially circular.
    (substitute_in_interval): Take a struct subst * rather than a
    Lisp_Object, for the closure data.  All callers changed.
    * test/src/lread-tests.el (lread-lread--substitute-object-in-subtree):
    New test, to check that the core dump does not reoccur.
lread.c 149 KB