1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

history expansion: add missing bounds check

So far all ksh versions accept event numbers referring to
nonexistent history events in history expansion (-H/-o histexpand),
e.g. !9999 is accepted even if the history file has no item 9999.
These expansions seem to show random content from the history file,
sometimes including binary data. Of course an "event not found"
error should have been thrown instead.

hist_expand() in hexpand.c calls hist_seek() (from history.c)
without any bounds checking except verifying the history event
number is greater than zero. This commit adds a bounds check
to hist_seek() itself as it's called from three other places
in history.c, so perhaps this fixes a few other bugs as well.

src/cmd/ksh93/edit/history.c: hist_seek():
- Use the hist_min() and hist_max() macros provided in history.h
  to check bounds. Note that hist_max() yields the number of the
  command line currently being entered, so the maximum for seeking
  purposes is actually its result minus 1.
This commit is contained in:
Martijn Dekker 2022-01-21 01:18:34 +00:00
parent eaf7662daa
commit 8afc4756e8
3 changed files with 17 additions and 0 deletions

3
NEWS
View file

@ -5,6 +5,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
2022-01-20:
- Disallow out-of-range event numbers in history expansion (-H/-o histexpand).
Previously these were accepted, resulting in corrupted expansions.
- Fixed a potential crash in history expansion due to a buffer overflow.
2022-01-12:

View file

@ -846,6 +846,8 @@ off_t hist_tell(register History_t *hp, int n)
*/
off_t hist_seek(register History_t *hp, int n)
{
if(!(n >= hist_min(hp) && n < hist_max(hp)))
return(-1);
return(sfseek(hp->histfp,hp->histcmds[hist_ind(hp,n)],SEEK_SET));
}

View file

@ -958,5 +958,17 @@ r ^:test-1: echo $tmp/foo\\\\ bar \\r\\n$
r ^$tmp/foo bar\\r\\n$
!
((SHOPT_HISTEXPAND)) && HISTFILE=$tmp/tmp_histfile tst $LINENO <<!
L history expansion of an out-of-range event
d 15
p :test-1:
w set -H
p :test-2:
w echo "!99"
r !99
r : !99: event not found\r\n$
!
# ======
exit $((Errors<125?Errors:125))