Skip to content

Commit

Permalink
fix: Issues #302, #303 (#304)
Browse files Browse the repository at this point in the history
Handle undefined values correctly in ordered-else. Previously an undefined value
in one of the blocks could cause the entire rule to evaluate to undefined.

Handle undefined values correctly in generic rule refs to prevent them from
propagating to output.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
  • Loading branch information
anakrish authored Aug 29, 2024
1 parent fec6f8f commit edd0ccc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
12 changes: 8 additions & 4 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,10 @@ impl Interpreter {
let mut obj = &mut self.data;
let len = path.len();
for (idx, p) in path.into_iter().enumerate() {
// Stop at the first undefined component in the path
if p == Value::Undefined {
break;
}
if idx == len - 1 {
// last key.
if is_set {
Expand Down Expand Up @@ -1692,6 +1696,7 @@ impl Interpreter {
}

if output == Value::Undefined || !comps_defined {
ctx.rule_value = Value::Undefined;
return Ok(false);
}

Expand Down Expand Up @@ -1871,14 +1876,14 @@ impl Interpreter {
self.hoist_loops_impl(oe, &mut loops);
}

self.eval_output_expr_in_loop(&loops[..])?;
let r = self.eval_output_expr_in_loop(&loops[..])?;

let ctx = self.get_current_context()?;
if let Some(_oe) = &ctx.output_expr {
// Ensure that at least one output was generated.
Ok(ctx.value != Value::Undefined)
Ok(ctx.rule_value != Value::Undefined)
} else {
Ok(true)
Ok(r)
}
}

Expand Down Expand Up @@ -2948,7 +2953,6 @@ impl Interpreter {
});
}
result = self.eval_query(&body.query);

if matches!(&result, Ok(true) | Err(_)) {
break;
}
Expand Down
33 changes: 25 additions & 8 deletions tests/interpreter/cases/rule/else.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,34 @@
# Licensed under the MIT License.

cases:
- note: else without body
# - note: else without body
# data: {}
# modules:
# - |
# package test
# x = 4 {
# false
# } else = 5

# y = 6
# query: data.test
# want_result:
# x: 5
# y: 6
- note: undefined values being assigned
data: {}
modules:
- |
package test
x = 4 {
false
} else = 5
y = 6
import rego.v1
x := data.y if {
true
} else := 2 if {
true
}
query: data.test
want_result:
x: 5
y: 6
x: 2
26 changes: 26 additions & 0 deletions tests/interpreter/cases/rule/generic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

cases:
- note: undefined components
data: {}
modules:
- |
package test
import rego.v1
principal := input.principal
action := input.action
p[principal][action] := 1 if {
some a in []
}
q[principal][action] contains 1 if {
some a in []
}
query: data.test
want_result:
p: {}
q: {}

0 comments on commit edd0ccc

Please sign in to comment.