diff options
| author | Eli Zaretskii | 2010-04-25 20:06:41 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2010-04-25 20:06:41 +0300 |
| commit | 6bdf5d652360b79c8ee6194e8dd1b23ef4721a53 (patch) | |
| tree | 4c358911c21253b0980ee4cd4c7dc088b34ad896 /src | |
| parent | 7ac82b84051a250bf529a0a83e68dacac39a948d (diff) | |
| parent | f538fcec9abe33859fe4b7d84ea1d5a07d476469 (diff) | |
| download | emacs-6bdf5d652360b79c8ee6194e8dd1b23ef4721a53.tar.gz emacs-6bdf5d652360b79c8ee6194e8dd1b23ef4721a53.zip | |
Fix crash with bidi display on the last empty line (bug#6030).
xdisp.c (display_line): Don't assume 2nd call to
get_next_display_element cannot return zero. (Bug#6030)
Move code that bidi-iterates out of display property to a separate function.
xdisp.c (iterate_out_of_display_property): New function, body from pop_it.
(pop_it): Use it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/xdisp.c | 52 |
2 files changed, 37 insertions, 22 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2119d642ec0..e7ed7c36f78 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2010-04-25 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (display_line): Don't assume 2nd call to | ||
| 4 | get_next_display_element cannot return zero. (Bug#6030) | ||
| 5 | (iterate_out_of_display_property): New function, body from pop_it. | ||
| 6 | (pop_it): Use it. | ||
| 7 | |||
| 1 | 2010-04-24 Glenn Morris <rgm@gnu.org> | 8 | 2010-04-24 Glenn Morris <rgm@gnu.org> |
| 2 | 9 | ||
| 3 | * m/amdx86-64.h (START_FILES, LIB_STANDARD) [__OpenBSD__]: | 10 | * m/amdx86-64.h (START_FILES, LIB_STANDARD) [__OpenBSD__]: |
diff --git a/src/xdisp.c b/src/xdisp.c index 5e5684a845d..4834b61a626 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -5259,6 +5259,33 @@ push_it (it) | |||
| 5259 | ++it->sp; | 5259 | ++it->sp; |
| 5260 | } | 5260 | } |
| 5261 | 5261 | ||
| 5262 | static void | ||
| 5263 | iterate_out_of_display_property (it) | ||
| 5264 | struct it *it; | ||
| 5265 | { | ||
| 5266 | /* Maybe initialize paragraph direction. If we are at the beginning | ||
| 5267 | of a new paragraph, next_element_from_buffer may not have a | ||
| 5268 | chance to do that. */ | ||
| 5269 | if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) | ||
| 5270 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | ||
| 5271 | /* prev_stop can be zero, so check against BEGV as well. */ | ||
| 5272 | while (it->bidi_it.charpos >= BEGV | ||
| 5273 | && it->prev_stop <= it->bidi_it.charpos | ||
| 5274 | && it->bidi_it.charpos < CHARPOS (it->position)) | ||
| 5275 | bidi_get_next_char_visually (&it->bidi_it); | ||
| 5276 | /* Record the stop_pos we just crossed, for when we cross it | ||
| 5277 | back, maybe. */ | ||
| 5278 | if (it->bidi_it.charpos > CHARPOS (it->position)) | ||
| 5279 | it->prev_stop = CHARPOS (it->position); | ||
| 5280 | /* If we ended up not where pop_it put us, resync IT's | ||
| 5281 | positional members with the bidi iterator. */ | ||
| 5282 | if (it->bidi_it.charpos != CHARPOS (it->position)) | ||
| 5283 | { | ||
| 5284 | SET_TEXT_POS (it->position, | ||
| 5285 | it->bidi_it.charpos, it->bidi_it.bytepos); | ||
| 5286 | it->current.pos = it->position; | ||
| 5287 | } | ||
| 5288 | } | ||
| 5262 | 5289 | ||
| 5263 | /* Restore IT's settings from IT->stack. Called, for example, when no | 5290 | /* Restore IT's settings from IT->stack. Called, for example, when no |
| 5264 | more overlay strings must be processed, and we return to delivering | 5291 | more overlay strings must be processed, and we return to delivering |
| @@ -5309,25 +5336,7 @@ pop_it (it) | |||
| 5309 | determine the paragraph base direction if the overlay we | 5336 | determine the paragraph base direction if the overlay we |
| 5310 | just processed is at the beginning of a new | 5337 | just processed is at the beginning of a new |
| 5311 | paragraph. */ | 5338 | paragraph. */ |
| 5312 | if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) | 5339 | iterate_out_of_display_property (it); |
| 5313 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | ||
| 5314 | /* prev_stop can be zero, so check against BEGV as well. */ | ||
| 5315 | while (it->bidi_it.charpos >= BEGV | ||
| 5316 | && it->prev_stop <= it->bidi_it.charpos | ||
| 5317 | && it->bidi_it.charpos < CHARPOS (it->position)) | ||
| 5318 | bidi_get_next_char_visually (&it->bidi_it); | ||
| 5319 | /* Record the stop_pos we just crossed, for when we cross it | ||
| 5320 | back, maybe. */ | ||
| 5321 | if (it->bidi_it.charpos > CHARPOS (it->position)) | ||
| 5322 | it->prev_stop = CHARPOS (it->position); | ||
| 5323 | /* If we ended up not where pop_it put us, resync IT's | ||
| 5324 | positional members with the bidi iterator. */ | ||
| 5325 | if (it->bidi_it.charpos != CHARPOS (it->position)) | ||
| 5326 | { | ||
| 5327 | SET_TEXT_POS (it->position, | ||
| 5328 | it->bidi_it.charpos, it->bidi_it.bytepos); | ||
| 5329 | it->current.pos = it->position; | ||
| 5330 | } | ||
| 5331 | } | 5340 | } |
| 5332 | break; | 5341 | break; |
| 5333 | case GET_FROM_STRING: | 5342 | case GET_FROM_STRING: |
| @@ -17979,9 +17988,8 @@ display_line (it) | |||
| 17979 | row_end = it->current; | 17988 | row_end = it->current; |
| 17980 | /* If the character at max_pos+1 is a newline, skip that as | 17989 | /* If the character at max_pos+1 is a newline, skip that as |
| 17981 | well. Note that this may skip some invisible text. */ | 17990 | well. Note that this may skip some invisible text. */ |
| 17982 | if (!get_next_display_element (it)) | 17991 | if (get_next_display_element (it) |
| 17983 | abort (); | 17992 | && ITERATOR_AT_END_OF_LINE_P (it)) |
| 17984 | if (ITERATOR_AT_END_OF_LINE_P (it)) | ||
| 17985 | { | 17993 | { |
| 17986 | set_iterator_to_next (it, 1); | 17994 | set_iterator_to_next (it, 1); |
| 17987 | /* Record the position after the newline of a continued | 17995 | /* Record the position after the newline of a continued |