bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Fix history deletion when using negative offsets (from the end)


From: Christopher Gurnee
Subject: [PATCH] Fix history deletion when using negative offsets (from the end)
Date: Thu, 25 Feb 2021 14:06:32 -0500
User-agent: RoundCube WebMail

Bash Version: 5.1
Patch Level: 4
Release Status: release
Git Commit: f3a35a2d (current master)

I don't really know the contribution rules for bash; my apologies in advance if I'm missing anything or otherwise doing something wrong.

Description:

`history -d -#` can sometimes fail with the error `-bash: history: -#: history position out of range` even when the history entry is present.

Repeat-By:

(Note that all of the `history` commands below are prefixed by a space to prevent adding them to history.)

    test:~$ HISTCONTROL=ignorespace
    test:~$ HISTSIZE=4
    test:~$  history -c
    test:~$ echo 1 >/dev/null
    test:~$ echo 2 >/dev/null
    test:~$ echo 3 >/dev/null
    test:~$ echo 4 >/dev/null
    test:~$ echo 5 >/dev/null
    test:~$ echo 6 >/dev/null
    test:~$  history
        3  echo 3 >/dev/null
        4  echo 4 >/dev/null
        5  echo 5 >/dev/null
        6  echo 6 >/dev/null
    test:~$  history -d -1
    test:~$  history
        3  echo 3 >/dev/null
        4  echo 4 >/dev/null
        5  echo 5 >/dev/null
    test:~$ echo 6 >/dev/null
    test:~$ echo 7 >/dev/null
    test:~$  history
        4  echo 4 >/dev/null
        5  echo 5 >/dev/null
        6  echo 6 >/dev/null
        7  echo 7 >/dev/null
    test:~$  history -d -1
    -bash: history: -1: history position out of range

Fix:

Attached. In the code below from history.def, after `ind` is first assigned to, it should be in the range [0, history_length) if it refers to a valid entry. It's then compared to `history_base`, however it should be compared to `0` instead, e.g. `if (ind < 0)`.

    if (delete_arg[0] == '-' && delete_offset < 0)
      {
/* since the_history[history_length] == 0x0, this calculation means that history -d -1 will delete the last history entry, which at
           this point is the history -d -1 we just added. */
        ind = history_length + delete_offset;
        if (ind < history_base)
          {
            sh_erange (delete_arg, _("history position"));
            return (EXECUTION_FAILURE);
          }
opt = ind + history_base; /* compensate for opt - history_base below */
      }

After applying the patch, everything seems to work as intended, however I didn't look into how to write a test for this....

Regards,
Chris Gurnee

Attachment: history.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]