mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
Fix bug #9284 with line/wrap-prefix property on display strings.
src/xdisp.c (iterate_out_of_display_property): xassert that IT->position is set to within IT->object's boundaries. Break from the loop as soon as EOB is reached; avoids infloops in redisplay when IT->position is set up wrongly due to some bug. Set IT->current to match the bidi iterator unconditionally. (push_display_prop): Allow GET_FROM_STRING as IT->method on entry; avoids crashes when line/wrap-prefix is set on a display string. Force push_it to save on the stack the current buffer/string position, to be restored by pop_it. Fix flags in the iterator structure wrt the object coming from a display property, as `line-prefix' and `wrap-prefix' are not ``replacing'' properties.
This commit is contained in:
parent
9d5cb6312b
commit
08fff70c6e
2 changed files with 39 additions and 18 deletions
|
|
@ -1,3 +1,17 @@
|
||||||
|
2011-08-12 Eli Zaretskii <eliz@gnu.org>
|
||||||
|
|
||||||
|
* xdisp.c (iterate_out_of_display_property): xassert that
|
||||||
|
IT->position is set to within IT->object's boundaries. Break from
|
||||||
|
the loop as soon as EOB is reached; avoids infloops in redisplay
|
||||||
|
when IT->position is set up wrongly due to some bug. Set
|
||||||
|
IT->current to match the bidi iterator unconditionally.
|
||||||
|
(push_display_prop): Allow GET_FROM_STRING as IT->method on
|
||||||
|
entry. Force push_it to save on the stack the current
|
||||||
|
buffer/string position, to be restored by pop_it. Fix flags in
|
||||||
|
the iterator structure wrt the object coming from a display
|
||||||
|
property, as `line-prefix' and `wrap-prefix' are not ``replacing''
|
||||||
|
properties. (Bug#9284)
|
||||||
|
|
||||||
2011-08-09 Andreas Schwab <schwab@linux-m68k.org>
|
2011-08-09 Andreas Schwab <schwab@linux-m68k.org>
|
||||||
|
|
||||||
* fontset.c (fontset_get_font_group): Add proper type checks.
|
* fontset.c (fontset_get_font_group): Add proper type checks.
|
||||||
|
|
|
||||||
35
src/xdisp.c
35
src/xdisp.c
|
|
@ -5326,6 +5326,8 @@ iterate_out_of_display_property (struct it *it)
|
||||||
EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
|
EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
|
||||||
EMACS_INT bob = (buffer_p ? BEGV : 0);
|
EMACS_INT bob = (buffer_p ? BEGV : 0);
|
||||||
|
|
||||||
|
xassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
|
||||||
|
|
||||||
/* Maybe initialize paragraph direction. If we are at the beginning
|
/* Maybe initialize paragraph direction. If we are at the beginning
|
||||||
of a new paragraph, next_element_from_buffer may not have a
|
of a new paragraph, next_element_from_buffer may not have a
|
||||||
chance to do that. */
|
chance to do that. */
|
||||||
|
|
@ -5334,7 +5336,8 @@ iterate_out_of_display_property (struct it *it)
|
||||||
/* prev_stop can be zero, so check against BEGV as well. */
|
/* prev_stop can be zero, so check against BEGV as well. */
|
||||||
while (it->bidi_it.charpos >= bob
|
while (it->bidi_it.charpos >= bob
|
||||||
&& it->prev_stop <= it->bidi_it.charpos
|
&& it->prev_stop <= it->bidi_it.charpos
|
||||||
&& it->bidi_it.charpos < CHARPOS (it->position))
|
&& it->bidi_it.charpos < CHARPOS (it->position)
|
||||||
|
&& it->bidi_it.charpos < eob)
|
||||||
bidi_move_to_visually_next (&it->bidi_it);
|
bidi_move_to_visually_next (&it->bidi_it);
|
||||||
/* Record the stop_pos we just crossed, for when we cross it
|
/* Record the stop_pos we just crossed, for when we cross it
|
||||||
back, maybe. */
|
back, maybe. */
|
||||||
|
|
@ -5343,14 +5346,11 @@ iterate_out_of_display_property (struct it *it)
|
||||||
/* If we ended up not where pop_it put us, resync IT's
|
/* If we ended up not where pop_it put us, resync IT's
|
||||||
positional members with the bidi iterator. */
|
positional members with the bidi iterator. */
|
||||||
if (it->bidi_it.charpos != CHARPOS (it->position))
|
if (it->bidi_it.charpos != CHARPOS (it->position))
|
||||||
{
|
SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
|
||||||
SET_TEXT_POS (it->position,
|
|
||||||
it->bidi_it.charpos, it->bidi_it.bytepos);
|
|
||||||
if (buffer_p)
|
if (buffer_p)
|
||||||
it->current.pos = it->position;
|
it->current.pos = it->position;
|
||||||
else
|
else
|
||||||
it->current.string_pos = it->position;
|
it->current.string_pos = it->position;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore IT's settings from IT->stack. Called, for example, when no
|
/* Restore IT's settings from IT->stack. Called, for example, when no
|
||||||
|
|
@ -18056,16 +18056,25 @@ cursor_row_p (struct glyph_row *row)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Push the display property PROP so that it will be rendered at the
|
/* Push the property PROP so that it will be rendered at the current
|
||||||
current position in IT. Return 1 if PROP was successfully pushed,
|
position in IT. Return 1 if PROP was successfully pushed, 0
|
||||||
0 otherwise. */
|
otherwise. Called from handle_line_prefix to handle the
|
||||||
|
`line-prefix' and `wrap-prefix' properties. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
push_display_prop (struct it *it, Lisp_Object prop)
|
push_display_prop (struct it *it, Lisp_Object prop)
|
||||||
{
|
{
|
||||||
xassert (it->method == GET_FROM_BUFFER);
|
struct text_pos pos =
|
||||||
|
(it->method == GET_FROM_STRING) ? it->current.string_pos : it->current.pos;
|
||||||
|
|
||||||
push_it (it, NULL);
|
xassert (it->method == GET_FROM_BUFFER
|
||||||
|
|| it->method == GET_FROM_STRING);
|
||||||
|
|
||||||
|
/* We need to save the current buffer/string position, so it will be
|
||||||
|
restored by pop_it, because iterate_out_of_display_property
|
||||||
|
depends on that being set correctly, but some situations leave
|
||||||
|
it->position not yet set when this function is called. */
|
||||||
|
push_it (it, &pos);
|
||||||
|
|
||||||
if (STRINGP (prop))
|
if (STRINGP (prop))
|
||||||
{
|
{
|
||||||
|
|
@ -18084,11 +18093,9 @@ push_display_prop (struct it *it, Lisp_Object prop)
|
||||||
it->stop_charpos = 0;
|
it->stop_charpos = 0;
|
||||||
it->prev_stop = 0;
|
it->prev_stop = 0;
|
||||||
it->base_level_stop = 0;
|
it->base_level_stop = 0;
|
||||||
it->string_from_display_prop_p = 1;
|
|
||||||
it->from_disp_prop_p = 1;
|
|
||||||
|
|
||||||
/* Force paragraph direction to be that of the parent
|
/* Force paragraph direction to be that of the parent
|
||||||
buffer. */
|
buffer/string. */
|
||||||
if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
|
if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
|
||||||
it->paragraph_embedding = it->bidi_it.paragraph_dir;
|
it->paragraph_embedding = it->bidi_it.paragraph_dir;
|
||||||
else
|
else
|
||||||
|
|
@ -18101,7 +18108,7 @@ push_display_prop (struct it *it, Lisp_Object prop)
|
||||||
it->bidi_it.string.s = NULL;
|
it->bidi_it.string.s = NULL;
|
||||||
it->bidi_it.string.schars = it->end_charpos;
|
it->bidi_it.string.schars = it->end_charpos;
|
||||||
it->bidi_it.string.bufpos = IT_CHARPOS (*it);
|
it->bidi_it.string.bufpos = IT_CHARPOS (*it);
|
||||||
it->bidi_it.string.from_disp_str = 1;
|
it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
|
||||||
it->bidi_it.string.unibyte = !it->multibyte_p;
|
it->bidi_it.string.unibyte = !it->multibyte_p;
|
||||||
bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
|
bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue