aboutsummaryrefslogtreecommitdiffhomepage
path: root/expand.cpp
diff options
context:
space:
mode:
authorGravatar Kevin Ballard <kevin@sb.org>2014-08-20 22:01:24 -0700
committerGravatar Kevin Ballard <kevin@sb.org>2014-08-20 22:09:32 -0700
commitcc49042294aceb3ab30396eb5731e4ac0cf601bc (patch)
treeaa8b79cdcf55b3ca88f4f9db0685de2cef33a115 /expand.cpp
parent3981b644d68f6b6947b4a12810c2fa5e09da4e58 (diff)
Parse slices even for empty variables
When a variable is parsed as being empty, parse out the slice and validate the indexes anyway, behaving for slicing purposes as if the variable had a single empty value. Besides providing errors when expected, this also fixes the following: set -l foo echo "$foo[1]" This used to print "[1]", now it properly prints nothing.
Diffstat (limited to 'expand.cpp')
-rw-r--r--expand.cpp35
1 files changed, 34 insertions, 1 deletions
diff --git a/expand.cpp b/expand.cpp
index d75c6572..7388cb18 100644
--- a/expand.cpp
+++ b/expand.cpp
@@ -1155,10 +1155,10 @@ static int expand_variables_internal(parser_t &parser, wchar_t * const in, std::
for (size_t j=0; j<var_idx_list.size(); j++)
{
long tmp = var_idx_list.at(j);
- size_t var_src_pos = var_pos_list.at(j);
/* Check that we are within array bounds. If not, truncate the list to exit. */
if (tmp < 1 || (size_t)tmp > var_item_list.size())
{
+ size_t var_src_pos = var_pos_list.at(j);
/* The slice was parsed starting at stop_pos, so we have to add that to the error position */
append_syntax_error(errors,
slice_start + var_src_pos,
@@ -1255,6 +1255,39 @@ static int expand_variables_internal(parser_t &parser, wchar_t * const in, std::
}
else
{
+ // even with no value, we still need to parse out slice syntax
+ // Behave as though we had 1 value, so $foo[1] always works.
+ const size_t slice_start = stop_pos;
+ if (in[slice_start] == L'[')
+ {
+ wchar_t *slice_end;
+
+ if (parse_slice(in + slice_start, &slice_end, var_idx_list, var_pos_list, 1))
+ {
+ append_syntax_error(errors,
+ stop_pos,
+ L"Invalid index value");
+ is_ok = 0;
+ return is_ok;
+ }
+ 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
*/