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
|
}, nil
|
||||||
}
|
}
|
||||||
// we got something, overwrite the existing static str
|
// 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
|
return result, nil // replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import (
|
|||||||
"github.com/purpleidea/mgmt/lang/funcs"
|
"github.com/purpleidea/mgmt/lang/funcs"
|
||||||
"github.com/purpleidea/mgmt/lang/interfaces"
|
"github.com/purpleidea/mgmt/lang/interfaces"
|
||||||
"github.com/purpleidea/mgmt/lang/parser"
|
"github.com/purpleidea/mgmt/lang/parser"
|
||||||
|
"github.com/purpleidea/mgmt/lang/types"
|
||||||
"github.com/purpleidea/mgmt/util"
|
"github.com/purpleidea/mgmt/util"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"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{
|
exp := &ast.StmtProg{
|
||||||
Body: []interfaces.Stmt{
|
Body: []interfaces.Stmt{
|
||||||
&ast.StmtRes{
|
&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{
|
testCases = append(testCases, test{
|
||||||
name: "basic expansion",
|
name: "basic expansion",
|
||||||
ast: xast,
|
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