Fix grouping in new[1] conditional in skip_to_histexp to avoid overflow:
$ ./bash --norc -in <<< $': !-1:0'
bash-5.3$ : !-1:0
subst.c:2508:20: runtime error: addition of unsigned offset to
0x611000003240 overflowed to 0x61100000323f
ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61100000323f at
pc 0x000104881e24 bp 0x00016b71fb70 sp 0x00016b71fb68
Also fix the length check for values of slen < 4 (since slen is unsigned).
Alternatively, the check can just be removed since a shorter string will
fail the checks on the next line anyway.
[1]: https://git.gnu.org/cgit/bash.git/diff/subst.c?h=devel&id=044c1acc
---
subst.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/subst.c b/subst.c
index 67677d33..5cbe5d34 100644
--- a/subst.c
+++ b/subst.c
@@ -2505,8 +2505,8 @@ skip_to_histexp (const char *string, int start, const
char *delims, int flags)
continue;
}
else if (histexp_comsub && c == 'c' &&
- (i == 0) || shellbreak (string[i-1]) && /* incomplete reserved
word eligibility test */
- (i <= slen - 4) &&
+ (i == 0 || shellbreak (string[i-1])) && /* incomplete reserved
word eligibility test */
+ (i + 4 <= slen) &&
string[i+1] == 'a' && string[i+2] == 's' && string[i+3] == 'e' &&
(shellblank (string[i+4]) || string[i+4] == '\0'))
{
@@ -2516,8 +2516,8 @@ skip_to_histexp (const char *string, int start, const
char *delims, int flags)
continue;
}
else if (histexp_comsub && c == 'e' &&
- (i == 0) || shellbreak (string[i-1]) && /* incomplete reserved
word eligibility test */
- (i <= slen - 4) &&
+ (i == 0 || shellbreak (string[i-1])) && /* incomplete reserved
word eligibility test */
+ (i + 4 <= slen) &&
string[i+1] == 's' && string[i+2] == 'a' && string[i+3] == 'c' &&
(shellbreak (string[i+4]) || string[i+4] == '\0'))
{
--
2.53.0