internal/shader: bug fix: check the size of array initialization

Closes #3111
This commit is contained in:
Hajime Hoshi 2024-09-21 18:51:26 +09:00
parent 7bd3a05a45
commit e6d4eac218
3 changed files with 53 additions and 2 deletions

View File

@ -1038,8 +1038,14 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
cs.addError(e.Pos(), fmt.Sprintf("invalid composite literal type %s", t.String()))
return nil, nil, nil, false
}
if t.Main == shaderir.Array && t.Length == -1 {
t.Length = len(e.Elts)
if t.Main == shaderir.Array {
if t.Length == -1 {
t.Length = len(e.Elts)
} else if t.Length < len(e.Elts) {
// KeyValueExpr is not supported yet. Just compare the length.
cs.addError(e.Pos(), fmt.Sprintf("too many values in %s literal", t.String()))
return nil, nil, nil, false
}
}
idx := block.totalLocalVariableCount()

View File

@ -4363,3 +4363,44 @@ func Foo() int {
t.Error(err)
}
}
// Issue #3111
func TestSyntaxTooManyElementsAtInitialization(t *testing.T) {
cases := []struct {
stmt string
err bool
}{
{stmt: "_ = [-1]int{}", err: true},
{stmt: "_ = [-1]int{0}", err: true},
{stmt: "_ = [-1]int{0, 0}", err: true},
{stmt: "_ = [-1]int{0, 0, 0}", err: true},
{stmt: "_ = [0]int{}", err: false},
{stmt: "_ = [0]int{0}", err: true},
{stmt: "_ = [0]int{0, 0}", err: true},
{stmt: "_ = [0]int{0, 0, 0}", err: true},
{stmt: "_ = [1]int{}", err: false},
{stmt: "_ = [1]int{0}", err: false},
{stmt: "_ = [1]int{0, 0}", err: true},
{stmt: "_ = [1]int{0, 0, 0}", err: true},
{stmt: "_ = [2]int{}", err: false},
{stmt: "_ = [2]int{0}", err: false},
{stmt: "_ = [2]int{0, 0}", err: false},
{stmt: "_ = [2]int{0, 0, 0}", err: true},
}
for _, c := range cases {
stmt := c.stmt
src := fmt.Sprintf(`package main
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
%s
return dstPos
}`, stmt)
_, err := compileToIR([]byte(src))
if err == nil && c.err {
t.Errorf("%s must return an error but does not", stmt)
} else if err != nil && !c.err {
t.Errorf("%s must not return nil but returned %v", stmt, err)
}
}
}

View File

@ -81,6 +81,10 @@ func (cs *compileState) parseType(block *block, fname string, expr ast.Expr) (sh
cs.addError(t.Pos(), "length of array must be an integer")
return shaderir.Type{}, false
}
if l < 0 {
cs.addError(t.Pos(), fmt.Sprintf("invalid length array %d", l))
return shaderir.Type{}, false
}
length = int(l)
}