Package: joe Version: 3.7 Severity: important Tags: upstream patch Dear Maintainer,
This is a clone of this bug: https://sourceforge.net/p/joe-editor/bugs/295/ How to reproduce: 0. Start joe with an empty buffer. 1. Type abracadabra 2. Move the cursor to the beginning of the buffer. 3. Search-and replace the first 3 occurrences of a with X 4. Press Ctrl-<C> to abort the replace at the 4th occurrence of a. 5. Manually move the cursor, delete the last X and type an a instead. 6. Move the cursor to the beginning of the buffer. 7. Repeat the last seach-and-and-replace (Ctrl-<L>). 8. At this point joe falls to an infinite loop. The only way out is to kill it. I will include the **second** patch from the sourceforge bug. The author describes it as follows: "Maybe there is a more complicated issue here. This patch disables the infinite loop prevention feature provided by srch->last_repl. I tried to understand the code, but I couldn't figure out an example (I even tried replacing x with xxxyyy, and then replacing x with yyyxxx in wrap-around mode) which would benefit from this feature -- maybe it doesn't prevent any infinite loops at all, and it's just dead code?" I can confirm that the patch compiles on a couple of systems (Ubuntu, CentOs) and fixes the issue. Normal search-and-replace functionality still works. This is one of two patches that I am sending today. I think that together, they might warrant a new minor release, since these cover all the stability problems I've had with Joe in the past couple of years. Thanks, Alexey
>From a5ed11ba2afa8231821119da5542208b8ff65915 Mon Sep 17 00:00:00 2001 From: Alexey Spiridonov <[email protected]> Date: Mon, 21 Apr 2014 17:33:33 -0700 Subject: [PATCH] Remove infinite loop protection Summary: From http://sourceforge.net/p/joe-editor/bugs/295/ --- usearch.c | 48 ++++++++++++------------------------------------ 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/usearch.c b/usearch.c index 8a8eb6c..97589ed 100644 --- a/usearch.c +++ b/usearch.c @@ -245,8 +245,6 @@ static P *searchf(BW *bw,SRCH *srch, P *p) start = pdup(p, USTR "searchf"); end = pdup(p, USTR "searchf"); - try_again: - for (x = 0; x != sLEN(pattern) && pattern[x] != '\\' && (pattern[x]<128 || !p->b->o.charmap->type); ++x) if (srch->ignore) pattern[x] = joe_tolower(p->b->o.charmap,pattern[x]); @@ -257,22 +255,12 @@ static P *searchf(BW *bw,SRCH *srch, P *p) if (srch->wrap_flag && start->byte>=srch->wrap_p->byte) break; if (pmatch(srch->pieces, pattern + x, sLEN(pattern) - x, end, 0, srch->ignore)) { - if (end->byte == srch->last_repl) { - /* Stuck? */ - pattern = srch->pattern; - pset(start, p); - if (pgetc(start) == NO_MORE_DATA) - break; - pset(end, start); - goto try_again; - } else { - srch->entire = vstrunc(srch->entire, (int) (end->byte - start->byte)); - brmem(start, srch->entire, (int) (end->byte - start->byte)); - pset(p, end); - prm(start); - prm(end); - return p; - } + srch->entire = vstrunc(srch->entire, (int) (end->byte - start->byte)); + brmem(start, srch->entire, (int) (end->byte - start->byte)); + pset(p, end); + prm(start); + prm(end); + return p; } if (pgetc(start) == NO_MORE_DATA) break; @@ -313,8 +301,6 @@ static P *searchb(BW *bw,SRCH *srch, P *p) start = pdup(p, USTR "searchb"); end = pdup(p, USTR "searchb"); - try_again: - for (x = 0; x != sLEN(pattern) && pattern[x] != '\\' && (pattern[x]<128 || !p->b->o.charmap->type); ++x) if (srch->ignore) pattern[x] = joe_tolower(p->b->o.charmap,pattern[x]); @@ -327,22 +313,12 @@ static P *searchb(BW *bw,SRCH *srch, P *p) if (srch->wrap_flag && start->byte<srch->wrap_p->byte) break; if (pmatch(srch->pieces, pattern + x, sLEN(pattern) - x, end, 0, srch->ignore)) { - if (start->byte == srch->last_repl) { - /* Stuck? */ - pattern = srch->pattern; - pset(start, p); - if (prgetc(start) == NO_MORE_DATA) - break; - pset(end, start); - goto try_again; - } else { - srch->entire = vstrunc(srch->entire, (int) (end->byte - start->byte)); - brmem(start, srch->entire, (int) (end->byte - start->byte)); - pset(p, start); - prm(start); - prm(end); - return p; - } + srch->entire = vstrunc(srch->entire, (int) (end->byte - start->byte)); + brmem(start, srch->entire, (int) (end->byte - start->byte)); + pset(p, start); + prm(start); + prm(end); + return p; } } -- 1.8.3.2

