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

Reply via email to