[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#7876: Crash: infinite recursion in next_element_from_buffer
From: |
Stefan Monnier |
Subject: |
bug#7876: Crash: infinite recursion in next_element_from_buffer |
Date: |
Mon, 24 Jan 2011 17:09:58 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) |
Thanks a lot, Eli, I think I've found the problem:
the stop_pos is stuck there, because it's the end of the buffer, but
end_charpos points further than ZV.
The reason for that is that grep.el's font-lock code doesn't just
add/remove text properties but also removes text. In the old
compile.el, jit-lock is disabled so font-lock is run when the text is
inserted, but with my new compile.el, jit-lock can be (and is, by
default) enabled, so the end_charpos becomes invalid after running
jit-lock, and the redisplay code doesn't seem to pay attention to
this possibility.
I'm not very happy with grep.el's modifying the buffer like that from
font-lock-keywords, but neither is it OK for the redisplay to get stuck
in such an inf-loop.
I've installed the patch below in the emacs-23 branch, to account for
this particular case, although the jit-lock code could do nastier things
(e.g. add/remove text before the current position, thus rendering
IT_CHARPOS invalid).
Stefan
=== modified file 'src/xdisp.c'
--- src/xdisp.c 2011-01-02 23:50:46 +0000
+++ src/xdisp.c 2011-01-24 22:02:26 +0000
@@ -3337,6 +3337,8 @@
val = Vfontification_functions;
specbind (Qfontification_functions, Qnil);
+ xassert (it->end_charpos == ZV);
+
if (!CONSP (val) || EQ (XCAR (val), Qlambda))
safe_call1 (val, pos);
else
@@ -3376,6 +3378,13 @@
unbind_to (count, Qnil);
+ /* The fontification code may have added/removed text.
+ It could do even a lot worse, but let's at least protect against
+ the most obvious case where only the text past `pos' gets changed',
+ as is/was done in grep.el where some escapes sequences are turned
+ into face properties (bug#7876). */
+ it->end_charpos = ZV;
+
/* Return HANDLED_RECOMPUTE_PROPS only if function fontified
something. This avoids an endless loop if they failed to
fontify the text for which reason ever. */