lang: ast: Ensure a list doesn't sneak through type interpolation
If we had a single list wrapped in an interpolated string, it could sneak through type unification, which is not correct. Wrapping a variable by interpolation in a string, must force it to be a string.
This commit is contained in:
@@ -5408,6 +5408,10 @@ func (obj *ExprStr) Interpolate() (interfaces.Expr, error) {
|
||||
}, nil
|
||||
}
|
||||
// we got something, overwrite the existing static str
|
||||
// ensure str, to avoid a pass-through list in a simple interpolation
|
||||
if err := result.SetType(types.TypeStr); err != nil {
|
||||
return nil, errwrap.Wrapf(err, "interpolated string expected a different type")
|
||||
}
|
||||
return result, nil // replacement
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import (
|
||||
"github.com/purpleidea/mgmt/lang/funcs"
|
||||
"github.com/purpleidea/mgmt/lang/interfaces"
|
||||
"github.com/purpleidea/mgmt/lang/parser"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
"github.com/purpleidea/mgmt/util"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
@@ -384,6 +385,9 @@ func TestInterpolateBasicStmt(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := resName.SetType(types.TypeStr); err != nil {
|
||||
panic("could not set type")
|
||||
}
|
||||
exp := &ast.StmtProg{
|
||||
Body: []interfaces.Stmt{
|
||||
&ast.StmtRes{
|
||||
@@ -574,6 +578,9 @@ func TestInterpolateBasicExpr(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := exp.SetType(types.TypeStr); err != nil {
|
||||
panic("could not set type")
|
||||
}
|
||||
testCases = append(testCases, test{
|
||||
name: "basic expansion",
|
||||
ast: xast,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
-- main.mcl --
|
||||
$name = ["a", "bb", "ccc",]
|
||||
test $name {}
|
||||
test "test" {}
|
||||
|
||||
#Test[$name] -> Test["test"] # must pass
|
||||
Test["${name}"] -> Test["test"] # must fail
|
||||
|
||||
-- OUTPUT --
|
||||
# err: errUnify: can't unify, invariant illogicality with equality: base kind does not match (Str != List)
|
||||
@@ -0,0 +1,16 @@
|
||||
-- main.mcl --
|
||||
$name = ["a", "bb", "ccc",]
|
||||
test $name {}
|
||||
test "test" {}
|
||||
|
||||
Test[$name] -> Test["test"] # must pass
|
||||
#Test["${name}"] -> Test["test"] # must fail
|
||||
|
||||
-- OUTPUT --
|
||||
Edge: test[a] -> test[test] # test[a] -> test[test]
|
||||
Edge: test[bb] -> test[test] # test[bb] -> test[test]
|
||||
Edge: test[ccc] -> test[test] # test[ccc] -> test[test]
|
||||
Vertex: test[a]
|
||||
Vertex: test[bb]
|
||||
Vertex: test[ccc]
|
||||
Vertex: test[test]
|
||||
@@ -0,0 +1,10 @@
|
||||
-- main.mcl --
|
||||
$name = ["a", "bb", "ccc",]
|
||||
test $name {}
|
||||
test "test" {}
|
||||
|
||||
#Test["test"] -> Test[$name] # must pass
|
||||
Test["test"] -> Test["${name}"] # must fail
|
||||
|
||||
-- OUTPUT --
|
||||
# err: errUnify: can't unify, invariant illogicality with equality: base kind does not match (Str != List)
|
||||
@@ -0,0 +1,16 @@
|
||||
-- main.mcl --
|
||||
$name = ["a", "bb", "ccc",]
|
||||
test $name {}
|
||||
test "test" {}
|
||||
|
||||
Test["test"] -> Test[$name] # must pass
|
||||
#Test["test"] -> Test["${name}"] # must fail
|
||||
|
||||
-- OUTPUT --
|
||||
Edge: test[test] -> test[a] # test[test] -> test[a]
|
||||
Edge: test[test] -> test[bb] # test[test] -> test[bb]
|
||||
Edge: test[test] -> test[ccc] # test[test] -> test[ccc]
|
||||
Vertex: test[a]
|
||||
Vertex: test[bb]
|
||||
Vertex: test[ccc]
|
||||
Vertex: test[test]
|
||||
@@ -0,0 +1,8 @@
|
||||
-- main.mcl --
|
||||
$name = ["a", "bb", "ccc",]
|
||||
|
||||
#test $name {} # must pass
|
||||
test "${name}" {} # must fail
|
||||
|
||||
-- OUTPUT --
|
||||
# err: errUnify: can't unify, invariant illogicality with equality: base kind does not match (Str != List)
|
||||
@@ -0,0 +1,10 @@
|
||||
-- main.mcl --
|
||||
$name = ["a", "bb", "ccc",]
|
||||
|
||||
test $name {} # must pass
|
||||
#test "${name}" {} # must fail
|
||||
|
||||
-- OUTPUT --
|
||||
Vertex: test[a]
|
||||
Vertex: test[bb]
|
||||
Vertex: test[ccc]
|
||||
Reference in New Issue
Block a user