Fix core dump in substitute-object-in-subtree
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.
This commit is contained in:
parent
ce6773aad5
commit
083940a93d
7 changed files with 60 additions and 137 deletions
|
@ -906,7 +906,7 @@ circular objects. Let `read' read everything else."
|
|||
;; with the object itself, wherever it occurs.
|
||||
(forward-char 1)
|
||||
(let ((obj (edebug-read-storing-offsets stream)))
|
||||
(substitute-object-in-subtree obj placeholder)
|
||||
(lread--substitute-object-in-subtree obj placeholder t)
|
||||
(throw 'return (setf (cdr elem) obj)))))
|
||||
((eq ?# (following-char))
|
||||
;; #n# returns a previously read object.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue