diff --git a/src/expand.cpp b/src/expand.cpp index 837d90eba..458df0498 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -650,7 +650,7 @@ static size_t parse_slice(const wchar_t *in, wchar_t **end_ptr, std::vector -1 ? tmp : (long)array_size + tmp + 1; + long i1 = tmp > -1 ? tmp : size + tmp + 1; pos = end - in; while (in[pos] == INTERNAL_SEPARATOR) pos++; if (in[pos] == L'.' && in[pos + 1] == L'.') { @@ -667,6 +667,13 @@ static size_t parse_slice(const wchar_t *in, wchar_t **end_ptr, std::vector -1 ? tmp1 : size + tmp1 + 1; + // Clamp to array size, but only when doing a range, + // and only when just one is too high. + if (i1 > size && i2 > size) { + continue; + } + i1 = i1 < size ? i1 : size; + i2 = i2 < size ? i2 : size; // debug( 0, L"Push range idx %d %d", i1, i2 ); short direction = i2 < i1 ? -1 : 1; for (long jjj = i1; jjj * direction <= i2 * direction; jjj += direction) { diff --git a/tests/expansion.in b/tests/expansion.in index f1df97d57..cfdcfa366 100644 --- a/tests/expansion.in +++ b/tests/expansion.in @@ -80,6 +80,10 @@ show "$foo[1 2]" show $foo[1 2] show "$foo[2 1]" show $foo[2 1] +set -l foo a b c +show $foo[17] +show $foo[-17] +show $foo[17..18] echo "$foo[d]" echo $foo[d] diff --git a/tests/expansion.out b/tests/expansion.out index 3025cda9d..3f406cb30 100644 --- a/tests/expansion.out +++ b/tests/expansion.out @@ -52,5 +52,8 @@ 0 1 0 +0 +0 +0 Catch your breath