Subject: lib/26785: libedit - H_NEXT and H_PREV shifts cursor on failure
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <online@thrysoee.dk>
List: netbsd-bugs
Date: 08/28/2004 11:32:17
>Number:         26785
>Category:       lib
>Synopsis:       libedit - H_NEXT and H_PREV shifts cursor on failure
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Aug 28 11:33:01 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Jess Thrysoee
>Release:        CVS
>Organization:
>Environment:
N/A
>Description:
H_NEXT or H_PREV to start/end of history list. The last history step fails, but the cursor is still shifted, and now points to h->list.
>How-To-Repeat:
#include <histedit.h>

int
main(int argc, char* argv[])
{
   int res;
   History *h;
   HistEvent ev;

   h = history_init();

   history(h, &ev, H_ENTER, "1");
   history(h, &ev, H_ENTER, "2");

   /* rewind history */
   while (history(h, &ev, H_NEXT) != -1)
      ;

   history(h, &ev, H_CURR);
   fprintf(stdout, "%d - %s\n", ev.num, ev.str);
}

>Fix:
diff -Naur libedit/history.c libedit_patched/history.c
--- libedit/history.c	2004-08-20 14:54:05.000000000 +0200
+++ libedit_patched/history.c	2004-08-22 23:11:17.000000000 +0200
@@ -246,20 +246,19 @@
 {
 	history_t *h = (history_t *) p;
 
-	if (h->cursor != &h->list)
-		h->cursor = h->cursor->next;
-	else {
+	if (h->cursor == &h->list) {
 		he_seterrev(ev, _HE_EMPTY_LIST);
 		return (-1);
 	}
 
-	if (h->cursor != &h->list)
-		*ev = h->cursor->ev;
-	else {
+	if (h->cursor->next == &h->list) {
 		he_seterrev(ev, _HE_END_REACHED);
 		return (-1);
 	}
 
+        h->cursor = h->cursor->next;
+        *ev = h->cursor->ev;
+
 	return (0);
 }
 
@@ -272,21 +271,20 @@
 {
 	history_t *h = (history_t *) p;
 
-	if (h->cursor != &h->list)
-		h->cursor = h->cursor->prev;
-	else {
+	if (h->cursor == &h->list) {
 		he_seterrev(ev,
 		    (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
 		return (-1);
 	}
 
-	if (h->cursor != &h->list)
-		*ev = h->cursor->ev;
-	else {
+	if (h->cursor->prev == &h->list) {
 		he_seterrev(ev, _HE_START_REACHED);
 		return (-1);
 	}
 
+        h->cursor = h->cursor->prev;
+        *ev = h->cursor->ev;
+
 	return (0);
 }

>Release-Note:
>Audit-Trail:
>Unformatted: