From 03f2f0e9f43401b7615b7f37dcc866ac0dd1a7a8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 3 Sep 2023 19:16:51 +1000 Subject: [PATCH] render-lines: avoid looping indefinitely when shifting. If is used for markup when wrap is enabled, and if the cursor is at the end of the list, it is impossible to shift enough that there is room for the cursor after the text. So the shift loop continues endlessly. Put a hard limit on this, and use a consistent limit in the other places that we shift. Signed-off-by: NeilBrown --- render-lines.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/render-lines.c b/render-lines.c index b8580625..3b6567d2 100644 --- a/render-lines.c +++ b/render-lines.c @@ -658,12 +658,15 @@ static void find_lines(struct mark *pm safe, struct pane *p safe, if (start->mdata) { struct pane *hp = start->mdata; int curs_width; + int shifts = 0; found_end = measure_line(p, focus, start, offset) & 2; curs_width = pane_attr_get_int( start->mdata, "curs_width", 1); if (curs_width <= 0) curs_width = 1; + // FIXME this loops indefinitely if cursor after + // right-justified text. while (!rl->do_wrap && !rl->shift_locked && hp->cx + curs_width >= p->w) { int shift = 8 * curs_width; @@ -671,6 +674,8 @@ static void find_lines(struct mark *pm safe, struct pane *p safe, shift = hp->cx; rl->shift_left += shift; measure_line(p, focus, start, offset); + if (shifts++ > 100) + break; } /* ->cy is top of cursor, we want to measure from bottom */ line_height_pre = attr_find_int(start->mdata->attrs, "line-height"); @@ -1040,7 +1045,7 @@ static int revalidate_start(struct rl_data *rl safe, /* This loop is fragile and sometimes spins. So ensure we * never loop more than 1000 times. */ - if (pm && !rl->do_wrap && !rl->shift_locked && shifts++ < 1000) { + if (pm && !rl->do_wrap && !rl->shift_locked && shifts++ < 100) { int prefix_len; int curs_width; /* Need to check if side-shift is needed on cursor line */ @@ -1068,7 +1073,7 @@ static int revalidate_start(struct rl_data *rl safe, curs_width = pane_attr_get_int( m->mdata, "curs_width", 1); - while (hp->cx + curs_width > p->w && shifts++ < 1000) { + while (hp->cx + curs_width > p->w && shifts++ < 100) { int shift = 8 * curs_width; if (shift > hp->cx) shift = hp->cx; @@ -1083,7 +1088,7 @@ static int revalidate_start(struct rl_data *rl safe, while ((hp->cx < prefix_len || (cols-rl->shift_left) + curs_width * 8 + curs_width < p->w) && rl->shift_left > 0 && - shifts++ < 1000 && + shifts++ < 100 && hp->cx + curs_width * 8 < p->w) { int shift = 8 * curs_width; if (shift > rl->shift_left) -- 2.39.5