diff options
author | 2016-05-10 10:49:37 +0000 | |
---|---|---|
committer | 2016-05-10 10:49:37 +0000 | |
commit | dddc8490d90a7478ec6b2430fb09b5626543ec88 (patch) | |
tree | 28e152b4bd7def28fba67dde2d9817e4775d970e | |
parent | typo in comment (diff) | |
download | wireguard-openbsd-dddc8490d90a7478ec6b2430fb09b5626543ec88.tar.xz wireguard-openbsd-dddc8490d90a7478ec6b2430fb09b5626543ec88.zip |
Fix history_get():
* Respect history_base.
* Bail out early for arguments that are too small.
* Select entry by readline offset, not by editline event number.
* Restore history cursor in case of failure.
This fixes the test_remove() regression test.
Based on a patch from Bastian Maerkisch <bmaerkisch at web dot de>.
Dmitrij Czarkoff pointed out a flaw in it that i fixed.
OK czarkoff@.
-rw-r--r-- | lib/libedit/readline.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/lib/libedit/readline.c b/lib/libedit/readline.c index 853d3c9c4c4..3fae304361c 100644 --- a/lib/libedit/readline.c +++ b/lib/libedit/readline.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readline.c,v 1.24 2016/05/09 12:31:55 schwarze Exp $ */ +/* $OpenBSD: readline.c,v 1.25 2016/05/10 10:49:37 schwarze Exp $ */ /* $NetBSD: readline.c,v 1.91 2010/08/28 15:44:59 christos Exp $ */ /*- @@ -1358,25 +1358,37 @@ history_get(int num) if (h == NULL || e == NULL) rl_initialize(); + if (num < history_base) + return NULL; + /* save current position */ if (history(h, &ev, H_CURR) != 0) return NULL; curr_num = ev.num; - /* start from the oldest */ - if (history(h, &ev, H_LAST) != 0) - return NULL; /* error */ - - /* look forwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVDATA, num, &she.data)) - return NULL; + /* + * use H_DELDATA to set to nth history (without delete) by passing + * (void **)-1 -- as in history_set_pos + */ + if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0) + goto out; + /* get current entry */ + if (history(h, &ev, H_CURR) != 0) + goto out; + if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0) + goto out; she.line = ev.str; /* restore pointer to where it was */ (void)history(h, &ev, H_SET, curr_num); return &she; + +out: + /* restore pointer to where it was */ + (void)history(h, &ev, H_SET, curr_num); + return NULL; } |