mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Remove "Array index out of bounds" errors
This just removes every invalid index. That means with `set foo a b c` and the "show" function from tests/expand.in: - `show $foo[-5..-1]` prints "3 a b c" - `show $foo[-10..1]` prints "1 a" - `show $foo[2..5]` prints "2 b c" - `show $foo[1 3 7 2]` prints "3 a c b" and similar for command substitutions. Fixes #826.
This commit is contained in:
parent
df01547eab
commit
44f2f37bd4
4 changed files with 32 additions and 54 deletions
|
@ -796,29 +796,22 @@ static int expand_variables(const wcstring &instr, std::vector<completion_t> *ou
|
||||||
|
|
||||||
if (!all_vars) {
|
if (!all_vars) {
|
||||||
wcstring_list_t string_values(var_idx_list.size());
|
wcstring_list_t string_values(var_idx_list.size());
|
||||||
|
size_t k = 0;
|
||||||
for (size_t j = 0; j < var_idx_list.size(); j++) {
|
for (size_t j = 0; j < var_idx_list.size(); j++) {
|
||||||
long tmp = var_idx_list.at(j);
|
long tmp = var_idx_list.at(j);
|
||||||
// Check that we are within array bounds. If not, truncate the list to
|
// Check that we are within array bounds. If not, skip the element. Note:
|
||||||
// exit.
|
// Negative indices (`echo $foo[-1]`) are already converted to positive ones
|
||||||
if (tmp < 1 || (size_t)tmp > var_item_list.size()) {
|
// here, So tmp < 1 means it's definitely not in.
|
||||||
size_t var_src_pos = var_pos_list.at(j);
|
if ((size_t)tmp > var_item_list.size() || tmp < 1) {
|
||||||
// The slice was parsed starting at stop_pos, so we have to add that
|
continue;
|
||||||
// to the error position.
|
|
||||||
append_syntax_error(errors, slice_start + var_src_pos,
|
|
||||||
ARRAY_BOUNDS_ERR);
|
|
||||||
is_ok = false;
|
|
||||||
var_idx_list.resize(j);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// Replace each index in var_idx_list inplace with the string value
|
|
||||||
// at the specified index.
|
|
||||||
// al_set( var_idx_list, j, wcsdup((const wchar_t *)al_get(
|
|
||||||
// &var_item_list, tmp-1 ) ) );
|
|
||||||
string_values.at(j) = var_item_list.at(tmp - 1);
|
|
||||||
}
|
}
|
||||||
|
// Replace each index in var_idx_list inplace with the string value
|
||||||
|
// at the specified index.
|
||||||
|
string_values.at(k++) = var_item_list.at(tmp - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// string_values is the new var_item_list.
|
// string_values is the new var_item_list. Resize to remove invalid elements.
|
||||||
|
string_values.resize(k);
|
||||||
var_item_list = std::move(string_values);
|
var_item_list = std::move(string_values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -892,17 +885,6 @@ static int expand_variables(const wcstring &instr, std::vector<completion_t> *ou
|
||||||
return is_ok;
|
return is_ok;
|
||||||
}
|
}
|
||||||
stop_pos = (slice_end - in);
|
stop_pos = (slice_end - in);
|
||||||
|
|
||||||
// Validate that the parsed indexes are valid.
|
|
||||||
for (size_t j = 0; j < var_idx_list.size(); j++) {
|
|
||||||
long tmp = var_idx_list.at(j);
|
|
||||||
if (tmp != 1) {
|
|
||||||
size_t var_src_pos = var_pos_list.at(j);
|
|
||||||
append_syntax_error(errors, slice_start + var_src_pos, ARRAY_BOUNDS_ERR);
|
|
||||||
is_ok = 0;
|
|
||||||
return is_ok;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand a non-existing variable.
|
// Expand a non-existing variable.
|
||||||
|
@ -1090,10 +1072,8 @@ static int expand_cmdsubst(const wcstring &input, std::vector<completion_t> *out
|
||||||
tail_begin = slice_end;
|
tail_begin = slice_end;
|
||||||
for (i = 0; i < slice_idx.size(); i++) {
|
for (i = 0; i < slice_idx.size(); i++) {
|
||||||
long idx = slice_idx.at(i);
|
long idx = slice_idx.at(i);
|
||||||
if (idx < 1 || (size_t)idx > sub_res.size()) {
|
if ((size_t)idx > sub_res.size() || idx < 1) {
|
||||||
size_t pos = slice_source_positions.at(i);
|
continue;
|
||||||
append_syntax_error(errors, slice_begin - in + pos, ARRAY_BOUNDS_ERR);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
idx = idx - 1;
|
idx = idx - 1;
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,9 @@
|
||||||
fish: Array index out of bounds
|
|
||||||
show "$foo[2]"
|
|
||||||
^
|
|
||||||
fish: Array index out of bounds
|
|
||||||
show $foo[2]
|
|
||||||
^
|
|
||||||
fish: Array index out of bounds
|
|
||||||
show "$foo[1 2]"
|
|
||||||
^
|
|
||||||
fish: Array index out of bounds
|
|
||||||
show $foo[1 2]
|
|
||||||
^
|
|
||||||
fish: Array index out of bounds
|
|
||||||
show "$foo[2 1]"
|
|
||||||
^
|
|
||||||
fish: Array index out of bounds
|
|
||||||
show $foo[2 1]
|
|
||||||
^
|
|
||||||
fish: Invalid index value
|
fish: Invalid index value
|
||||||
echo "$foo[d]"
|
echo "$foo[d]"
|
||||||
^
|
^
|
||||||
fish: Invalid index value
|
fish: Invalid index value
|
||||||
echo $foo[d]
|
echo $foo[d]
|
||||||
^
|
^
|
||||||
fish: Array index out of bounds
|
|
||||||
echo ()[1]
|
|
||||||
^
|
|
||||||
fish: Invalid index value
|
fish: Invalid index value
|
||||||
echo ()[d]
|
echo ()[d]
|
||||||
^
|
^
|
||||||
|
|
|
@ -62,6 +62,12 @@ show "$$foo"
|
||||||
show $$foo
|
show $$foo
|
||||||
show "prefix$$foo"
|
show "prefix$$foo"
|
||||||
show prefix$$foo
|
show prefix$$foo
|
||||||
|
show $foo[-5..2]
|
||||||
|
show $foo[-2..-1]
|
||||||
|
show $foo[-10..-5]
|
||||||
|
show (printf '%s\n' $foo)[-5..2]
|
||||||
|
show (printf '%s\n' $foo)[-2..-1]
|
||||||
|
show (printf '%s\n' $foo)[-10..-5]
|
||||||
|
|
||||||
set -l foo
|
set -l foo
|
||||||
show "$foo[1]"
|
show "$foo[1]"
|
||||||
|
|
|
@ -36,8 +36,21 @@
|
||||||
2 baz quux
|
2 baz quux
|
||||||
1 prefixbaz quux fooest
|
1 prefixbaz quux fooest
|
||||||
2 prefixbaz prefixquux
|
2 prefixbaz prefixquux
|
||||||
|
2 bar
|
||||||
|
2 fooest
|
||||||
|
0
|
||||||
|
2 bar
|
||||||
|
2 fooest
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
1
|
1
|
||||||
0
|
0
|
||||||
1
|
1
|
||||||
0
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
|
||||||
Catch your breath
|
Catch your breath
|
||||||
|
|
Loading…
Reference in a new issue