aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2015-09-21 12:35:26 +0300
committerEli Zaretskii2015-09-21 12:35:26 +0300
commite2f0dd2f49d8638d20615bfa38e95a71202dd543 (patch)
tree1cc5aef3f8c01348621904b5062c963702b40e0a /src
parent18028318d8908d547d82e8e3159994c14bb47dce (diff)
downloademacs-e2f0dd2f49d8638d20615bfa38e95a71202dd543.tar.gz
emacs-e2f0dd2f49d8638d20615bfa38e95a71202dd543.zip
Avoid infinite recursion while displaying box face
* src/xdisp.c (face_before_or_after_it_pos): Fix calculation of the previous string/buffer character position under bidi iteration. (Bug#21428)
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 3eff61f3716..34b5ca3cced 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4014,21 +4014,23 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
4014 /* With bidi iteration, the character before the current 4014 /* With bidi iteration, the character before the current
4015 in the visual order cannot be found by simple 4015 in the visual order cannot be found by simple
4016 iteration, because "reverse" reordering is not 4016 iteration, because "reverse" reordering is not
4017 supported. Instead, we need to use the move_it_* 4017 supported. Instead, we need to start from the string
4018 family of functions. */ 4018 beginning and go all the way to the current string
4019 position, remembering the previous position. */
4019 /* Ignore face changes before the first visible 4020 /* Ignore face changes before the first visible
4020 character on this display line. */ 4021 character on this display line. */
4021 if (it->current_x <= it->first_visible_x) 4022 if (it->current_x <= it->first_visible_x)
4022 return it->face_id; 4023 return it->face_id;
4023 SAVE_IT (it_copy, *it, it_copy_data); 4024 SAVE_IT (it_copy, *it, it_copy_data);
4024 /* Implementation note: Since move_it_in_display_line 4025 IT_STRING_CHARPOS (it_copy) = 0;
4025 works in the iterator geometry, and thinks the first 4026 bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
4026 character is always the leftmost, even in R2L lines, 4027 while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it))
4027 we don't need to distinguish between the R2L and L2R 4028 {
4028 cases here. */ 4029 charpos = IT_STRING_CHARPOS (it_copy);
4029 move_it_in_display_line (&it_copy, SCHARS (it_copy.string), 4030 if (charpos >= SCHARS (it->string))
4030 it_copy.current_x - 1, MOVE_TO_X); 4031 break;
4031 charpos = IT_STRING_CHARPOS (it_copy); 4032 bidi_move_to_visually_next (&it_copy.bidi_it);
4033 }
4032 RESTORE_IT (it, it, it_copy_data); 4034 RESTORE_IT (it, it, it_copy_data);
4033 } 4035 }
4034 else 4036 else
@@ -4108,11 +4110,15 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
4108 { 4110 {
4109 if (before_p) 4111 if (before_p)
4110 { 4112 {
4113 int current_x;
4114
4111 /* With bidi iteration, the character before the current 4115 /* With bidi iteration, the character before the current
4112 in the visual order cannot be found by simple 4116 in the visual order cannot be found by simple
4113 iteration, because "reverse" reordering is not 4117 iteration, because "reverse" reordering is not
4114 supported. Instead, we need to use the move_it_* 4118 supported. Instead, we need to use the move_it_*
4115 family of functions. */ 4119 family of functions, and move to the previous
4120 character starting from the beginning of the visual
4121 line. */
4116 /* Ignore face changes before the first visible 4122 /* Ignore face changes before the first visible
4117 character on this display line. */ 4123 character on this display line. */
4118 if (it->current_x <= it->first_visible_x) 4124 if (it->current_x <= it->first_visible_x)
@@ -4123,8 +4129,9 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
4123 character is always the leftmost, even in R2L lines, 4129 character is always the leftmost, even in R2L lines,
4124 we don't need to distinguish between the R2L and L2R 4130 we don't need to distinguish between the R2L and L2R
4125 cases here. */ 4131 cases here. */
4126 move_it_in_display_line (&it_copy, ZV, 4132 current_x = it_copy.current_x;
4127 it_copy.current_x - 1, MOVE_TO_X); 4133 move_it_vertically_backward (&it_copy, 0);
4134 move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X);
4128 pos = it_copy.current.pos; 4135 pos = it_copy.current.pos;
4129 RESTORE_IT (it, it, it_copy_data); 4136 RESTORE_IT (it, it, it_copy_data);
4130 } 4137 }