Gunnar Evermann <ge204(a)eng.cam.ac.uk> writes:
> No narrowing necessary. What happens is that when inserting the "a"
> we call:
>
> signal_after_change(buf = 0x824000, start = 7, orig_end = 7, new_end = 8)
>
> this runs acf, which in turn deletes two characters, making bufz=6.
>
> Now we call report_extent_modification which calls
>
> map_extents(from = 7, to = 8, fn = 0x1cd3f8,...)
>
> but 7 and 8 are now outside the buffer range, therefore triggering
> the assert when converting them to byteinds.
Aha...! Good spotting. From the type of assert Shengo gets that might
very well be the same bug (at the very least the assert has to do with
running unexpectically against the buffer boundary).
> I am surprised we don't see this more often. What do people usually
> use this after-change stuff for?
To set up extents (i.e. font-locking)...Changing the buffer like this
is evil (allthough the new flyspell autocorrect stuff does also does
things like that, it just sets of a hook of things to do later on the
post-command hook/idle timer). Note that one doesn't notice this with
normal after-change-functions because it is very rare to have many of
them and because the positions are converted to lisp ints first and
thus are subject to validation when they are used.
> any suggestions for a fix?
The trivial change would be simply check the validity of the two
positions before using them to map over extents. This then simply
means "real changes to the buffer in after-change-functions loses"
(A quick test[1] shows that this corresponds to what FSF 20.4 does)
The fancy answer would be to use markers to preserve the positions
along calls to lisps. However doing that without allocating lots of
unneed trash markers might well be difficult
Jan
P.S. You might want to make your example into a test case.
Footnotes:
[1] Running
(switch-to-buffer "FOO")
(insert "123456")
(defun reportargs (&rest args)
(with-current-buffer (get-buffer-create "traceme")
(insert (format "%s\n" args))))
(defun acf (start end len)
(goto-char 4)
(delete-char 2))
(setq after-change-functions '(reportargs acf reportargs))
(insert "a")
shows that FSF 20.4 calls 'reportargs' with the same arguments (7 8
nil) both times.
Running this on "xenacs-21.1.8 -vanilla" makes XEmacs go mad!