Skip to content

Commit

Permalink
ast: Fix panic in parser post-processing of expressions
Browse files Browse the repository at this point in the history
This commit fixes a panic caught in the fuzzer due to misuse of
operands returned by expr.Operand().

Fixes open-policy-agent#2714

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
tsandall authored and patrick-east committed Sep 23, 2020
1 parent 428219c commit 2f97708
Showing 2 changed files with 28 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ast/parser_ext.go
Original file line number Diff line number Diff line change
@@ -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 {
20 changes: 20 additions & 0 deletions ast/parser_test.go
Original file line number Diff line number Diff line change
@@ -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{}{},

0 comments on commit 2f97708

Please sign in to comment.