Skip to content

Commit

Permalink
expand,interp: adapt to Bash 5.0 changes
Browse files Browse the repository at this point in the history
The order in which associative array keys and values are printed has
changed. Before it was sorting by key; now it appears to sort in an
arbitrary way, such as via the hash table.

'man bash' still doesn't document what the order is, so let's keep the
simple order and have the tests sort manually.

'${!a}' now errors if the variable is empty, so do that too.

Updates mvdan#346.
  • Loading branch information
mvdan committed Jan 19, 2019
1 parent 8fb18ad commit 89c5621
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 29 deletions.
16 changes: 7 additions & 9 deletions expand/param.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ func (cfg *Config) paramExp(pe *syntax.ParamExp) (string, error) {
for k := range vr.Map {
strs = append(strs, k)
}
} else if str != "" {
} else if !syntax.ValidName(str) {
return "", fmt.Errorf("invalid indirect expansion")
} else {
vr = cfg.Env.Get(str)
strs = append(strs, vr.String())
}
Expand Down Expand Up @@ -315,15 +317,11 @@ func (cfg *Config) varInd(vr Variable, idx syntax.ArithmExpr) (string, error) {
case Associative:
switch lit := nodeLit(idx); lit {
case "@", "*":
var strs []string
keys := make([]string, 0, len(vr.Map))
for k := range vr.Map {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
strs = append(strs, vr.Map[k])
strs := make([]string, 0, len(vr.Map))
for _, val := range vr.Map {
strs = append(strs, val)
}
sort.Strings(strs)
if lit == "*" {
return cfg.ifsJoin(strs), nil
}
Expand Down
9 changes: 2 additions & 7 deletions interp/interp.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,10 @@ func (r *Runner) updateExpandOpts() {
}

func (r *Runner) expandErr(err error) {
switch err := err.(type) {
case nil:
case expand.UnsetParameterError:
r.errf("%s\n", err.Message)
if err != nil {
r.errf("%v\n", err)
r.exit = 1
r.setErr(ShellExitStatus(r.exit))
default:
r.setErr(err)
r.exit = 1
}
}

Expand Down
28 changes: 16 additions & 12 deletions interp/interp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,12 @@ var fileCases = []struct {
{"a=(a bcd); echo ${#a} ${#a[@]} ${#a[*]} ${#a[1]}", "1 2 2 3\n"},
{"set -- a bc; echo ${#@} ${#*} $#", "2 2 2\n"},
{
"echo ${!a}; a=b; echo ${!a}; b=c; echo ${!a}",
"\n\nc\n",
"echo ${!a}; echo more",
"invalid indirect expansion\nexit status 1 #JUSTERR",
},
{
"a=b; echo ${!a}; b=c; echo ${!a}",
"\nc\n",
},
{
"a=foo; echo ${a:1}; echo ${a: -1}; echo ${a: -10}; echo ${a:5}",
Expand Down Expand Up @@ -1834,20 +1838,20 @@ set +o pipefail
"\n\nb\n\n",
},
{
`declare -A a=([x]=b [y]=c); echo ${a[@]}; echo ${a[*]}`,
"b c\nb c\n",
`declare -A a=([x]=b [y]=c); for e in ${a[@]}; do echo $e; done | sort`,
"b\nc\n",
},
{
`declare -A a=([y]=b [x]=c); echo ${a[@]}; echo ${a[*]}`,
"c b\nc b\n",
`declare -A a=([y]=b [x]=c); for e in ${a[*]}; do echo $e; done | sort`,
"b\nc\n",
},
{
`declare -A a=([x]=a); a["y"]=d; a["x"]=c; echo ${a[@]}`,
"c d\n",
`declare -A a=([x]=a); a["y"]=d; a["x"]=c; for e in ${a[@]}; do echo $e; done | sort`,
"c\nd\n",
},
{
`declare -A a=([x]=a); a[y]=d; a[x]=c; echo ${a[@]}`,
"c d\n",
`declare -A a=([x]=a); a[y]=d; a[x]=c; for e in ${a[@]}; do echo $e; done | sort`,
"c\nd\n",
},
{
// cheating a little; bash just did a=c
Expand All @@ -1866,10 +1870,10 @@ set +o pipefail
// weird assignments
{"a=b; a=(c d); echo ${a[@]}", "c d\n"},
{"a=(b c); a=d; echo ${a[@]}", "d c\n"},
{"declare -A a=([x]=b [y]=c); a=d; echo ${a[@]}", "d b c\n"},
{"declare -A a=([x]=b [y]=c); a=d; for e in ${a[@]}; do echo $e; done | sort", "b\nc\nd\n"},
{"i=3; a=b; a[i]=x; echo ${a[@]}", "b x\n"},
{"i=3; declare a=(b); a[i]=x; echo ${!a[@]}", "0 3\n"},
{"i=3; declare -A a=(['x']=b); a[i]=x; echo ${!a[@]}", "i x\n"},
{"i=3; declare -A a=(['x']=b); a[i]=x; for e in ${!a[@]}; do echo $e; done | sort", "i\nx\n"},

// declare
{"declare -B foo", "declare: invalid option \"-B\"\nexit status 2 #JUSTERR"},
Expand Down
2 changes: 1 addition & 1 deletion interp/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ var modCases = []struct {
return fmt.Errorf("blacklisted: %s", args[0])
},
src: "a=$(malicious)",
want: "blacklisted: malicious",
want: "blacklisted: malicious\nexit status 1",
},
{
name: "ExecBackground",
Expand Down

0 comments on commit 89c5621

Please sign in to comment.