From fb9d16530abeab54f0df2f7780b91622e1375ecf Mon Sep 17 00:00:00 2001 From: Torin Sandall Date: Wed, 23 Sep 2020 09:35:54 -0400 Subject: [PATCH] ast: Fix panic in parser post-processing of expressions This commit fixes a panic caught in the fuzzer due to misuse of operands returned by expr.Operand(). Fixes #2714 Signed-off-by: Torin Sandall --- ast/parser_ext.go | 8 ++++++++ ast/parser_test.go | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ast/parser_ext.go b/ast/parser_ext.go index f44ca2b64d..644169a487 100644 --- a/ast/parser_ext.go +++ b/ast/parser_ext.go @@ -164,6 +164,10 @@ func ParseRuleFromExpr(module *Module, expr *Expr) (*Rule, error) { if expr.IsAssignment() { lhs, rhs := expr.Operand(0), expr.Operand(1) + if lhs == nil || rhs == nil { + return nil, errors.New("assignment requires two operands") + } + rule, err := ParseCompleteDocRuleFromAssignmentExpr(module, lhs, rhs) if err == nil { @@ -203,6 +207,10 @@ func parseCompleteRuleFromEq(module *Module, expr *Expr) (rule *Rule, err error) }() lhs, rhs := expr.Operand(0), expr.Operand(1) + if lhs == nil || rhs == nil { + return nil, errors.New("assignment requires two operands") + } + rule, err = ParseCompleteDocRuleFromEqExpr(module, lhs, rhs) if err == nil { diff --git a/ast/parser_test.go b/ast/parser_test.go index b91440d516..5125732fa1 100644 --- a/ast/parser_test.go +++ b/ast/parser_test.go @@ -1970,6 +1970,22 @@ data = {"bar": 2}` package a f(x)[x] = x { true }` + assignNoOperands := ` + package a + assign()` + + assignOneOperand := ` + package a + assign(x)` + + eqNoOperands := ` + package a + eq()` + + eqOneOperand := ` + package a + eq(x)` + assertParseModuleError(t, "multiple expressions", multipleExprs) assertParseModuleError(t, "non-equality", nonEquality) assertParseModuleError(t, "non-var name", nonVarName) @@ -1987,6 +2003,10 @@ data = {"bar": 2}` assertParseModuleError(t, "number in ref", "package a\n12[3]()=4") assertParseModuleError(t, "rule with args and key", callWithRuleKeyPartialObject) assertParseModuleError(t, "rule with args and key", callWithRuleKeyPartialSet) + assertParseModuleError(t, "assign without operands", assignNoOperands) + assertParseModuleError(t, "assign with only one operand", assignOneOperand) + assertParseModuleError(t, "eq without operands", eqNoOperands) + assertParseModuleError(t, "eq with only one operand", eqOneOperand) if _, err := ParseRuleFromExpr(&Module{}, &Expr{ Terms: struct{}{},