Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cedar
Submodule cedar updated 36 files
+11 −0 .github/dependabot.yml
+12 −0 cedar-policy-cli/CHANGELOG.md
+4 −4 cedar-policy-cli/Cargo.toml
+1 −1 cedar-policy-cli/src/lib.rs
+3 −3 cedar-policy-core/Cargo.toml
+15 −39 cedar-policy-core/src/ast/expr.rs
+0 −3 cedar-policy-core/src/ast/expr_iterator.rs
+6 −0 cedar-policy-core/src/ast/ops.rs
+4 −0 cedar-policy-core/src/ast/policy.rs
+7 −8 cedar-policy-core/src/ast/restricted_expr.rs
+0 −1 cedar-policy-core/src/ast/value.rs
+15 −8 cedar-policy-core/src/est.rs
+4 −5 cedar-policy-core/src/est/err.rs
+6 −25 cedar-policy-core/src/est/expr.rs
+95 −96 cedar-policy-core/src/evaluator.rs
+24 −26 cedar-policy-core/src/evaluator/err.rs
+2 −3 cedar-policy-core/src/extensions/decimal.rs
+3 −4 cedar-policy-core/src/extensions/ipaddr.rs
+488 −293 cedar-policy-core/src/parser/cst_to_ast.rs
+5 −10 cedar-policy-core/src/parser/err.rs
+0 −1 cedar-policy-core/src/parser/text_to_cst.rs
+0 −1 cedar-policy-core/src/transitive_closure.rs
+4 −4 cedar-policy-formatter/Cargo.toml
+3 −3 cedar-policy-validator/Cargo.toml
+3 −4 cedar-policy-validator/src/human_schema/err.rs
+6 −0 cedar-policy-validator/src/human_schema/fmt.rs
+9 −4 cedar-policy-validator/src/human_schema/grammar.lalrpop
+251 −3 cedar-policy-validator/src/human_schema/test.rs
+9 −39 cedar-policy-validator/src/typecheck.rs
+2 −2 cedar-policy-validator/src/typecheck/test_expr.rs
+154 −1 cedar-policy-validator/src/typecheck/test_namespace.rs
+2 −2 cedar-policy-validator/src/typecheck/test_type_annotation.rs
+43 −10 cedar-policy/CHANGELOG.md
+4 −4 cedar-policy/Cargo.toml
+4 −7 cedar-policy/src/api.rs
+41 −0 cedar-policy/src/tests.rs
16 changes: 8 additions & 8 deletions cedar-lean/Cedar/Spec/Evaluator.lean
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ def intOrErr : Option Int64 → Result Value
def apply₁ : UnaryOp → Value → Result Value
| .not, .prim (.bool b) => ok !b
| .neg, .prim (.int i) => intOrErr i.neg?
| .mulBy c, .prim (.int i) => intOrErr (c.mul? i)
| .like p, .prim (.string s) => ok (wildcardMatch s p)
| .is ety, .prim (.entityUID uid) => ok (ety == uid.ty)
| _, _ => error .typeError
| .like p, .prim (.string s) => .ok (wildcardMatch s p)
| .is ety, .prim (.entityUID uid) => .ok (ety == uid.ty)
| _, _ => .error .typeError

def inₑ (uid₁ uid₂ : EntityUID) (es : Entities) : Bool :=
uid₁ == uid₂ || (es.ancestorsOrEmpty uid₁).contains uid₂
Expand All @@ -52,10 +51,11 @@ def apply₂ (op₂ : BinaryOp) (v₁ v₂ : Value) (es : Entities) : Result Val
| .lessEq, .prim (.int i), .prim (.int j) => ok ((i ≤ j): Bool)
| .add, .prim (.int i), .prim (.int j) => intOrErr (i.add? j)
| .sub, .prim (.int i), .prim (.int j) => intOrErr (i.sub? j)
| .contains, .set vs₁, _ => ok (vs₁.contains v₂)
| .containsAll, .set vs₁, .set vs₂ => ok (vs₂.subset vs₁)
| .containsAny, .set vs₁, .set vs₂ => ok (vs₁.intersects vs₂)
| .mem, .prim (.entityUID uid₁), .prim (.entityUID uid₂) => ok (inₑ uid₁ uid₂ es)
| .mul, .prim (.int i), .prim (.int j) => intOrErr (i.mul? j)
| .contains, .set vs₁, _ => .ok (vs₁.contains v₂)
| .containsAll, .set vs₁, .set vs₂ => .ok (vs₂.subset vs₁)
| .containsAny, .set vs₁, .set vs₂ => .ok (vs₁.intersects vs₂)
| .mem, .prim (.entityUID uid₁), .prim (.entityUID uid₂) => .ok (inₑ uid₁ uid₂ es)
| .mem, .prim (.entityUID uid₁), .set (vs) => inₛ uid₁ vs es
| _, _, _ => error .typeError

Expand Down
2 changes: 1 addition & 1 deletion cedar-lean/Cedar/Spec/Expr.lean
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ inductive Var where
inductive UnaryOp where
| not
| neg
| mulBy (i : Int64)
| like (p : Pattern)
| is (ety : EntityType)

Expand All @@ -46,6 +45,7 @@ inductive BinaryOp where
| lessEq
| add
| sub
| mul
| contains
| containsAll
| containsAny
Expand Down
17 changes: 11 additions & 6 deletions cedar-lean/Cedar/Thm/Validation/Typechecker/BinaryApp.lean
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ theorem type_of_int_cmp_is_sound {op₂ : BinaryOp} {x₁ x₂ : Expr} {c₁ c
}

theorem type_of_int_arith_inversion {op₂ : BinaryOp} {x₁ x₂ : Expr} {c c' : Capabilities} {env : Environment} {ty : CedarType}
(h₁ : op₂ = .add ∨ op₂ = .sub)
(h₁ : op₂ = .add ∨ op₂ = .sub ∨ op₂ = .mul)
(h₂ : typeOf (Expr.binaryApp op₂ x₁ x₂) c env = Except.ok (ty, c')) :
c' = ∅ ∧
ty = .int ∧
Expand All @@ -224,7 +224,7 @@ theorem type_of_int_arith_inversion {op₂ : BinaryOp} {x₁ x₂ : Expr} {c c'
simp [typeOf] at *
cases h₃ : typeOf x₁ c env <;> simp [h₃] at h₂
cases h₄ : typeOf x₂ c env <;> simp [h₄] at h₂
rcases h₁ with h₁ | h₁
rcases h₁ with h₁ | h₁ | h₁
all_goals {
subst h₁
simp [typeOfBinaryApp, err, ok] at h₂
Expand All @@ -238,7 +238,7 @@ theorem type_of_int_arith_inversion {op₂ : BinaryOp} {x₁ x₂ : Expr} {c c'
}

theorem type_of_int_arith_is_sound {op₂ : BinaryOp} {x₁ x₂ : Expr} {c₁ c₂ : Capabilities} {env : Environment} {ty : CedarType} {request : Request} {entities : Entities}
(h₀ : op₂ = .add ∨ op₂ = .sub)
(h₀ : op₂ = .add ∨ op₂ = .sub ∨ op₂ = .mul)
(h₁ : CapabilitiesInvariant c₁ request entities)
(h₂ : RequestAndEntitiesMatchEnvironment env request entities)
(h₃ : typeOf (Expr.binaryApp op₂ x₁ x₂) c₁ env = Except.ok (ty, c₂))
Expand Down Expand Up @@ -266,15 +266,19 @@ theorem type_of_int_arith_is_sound {op₂ : BinaryOp} {x₁ x₂ : Expr} {c₁ c
have ⟨i₁, ih₁⟩ := instance_of_int_is_int ih₃
have ⟨i₂, ih₂⟩ := instance_of_int_is_int ih₄
subst ih₁ ih₂
rcases h₀ with h₀ | h₀ <;> subst h₀ <;> simp [apply₂, intOrErr]
rcases h₀ with h₀ | h₀ | h₀ <;> subst h₀ <;> simp [apply₂, intOrErr]
case inl =>
cases h₄ : Int64.add? i₁ i₂ <;> simp [h₄]
case none => exact type_is_inhabited CedarType.int
case some => simp [InstanceOfType.instance_of_int]
case inr =>
case inr.inl =>
cases h₄ : Int64.sub? i₁ i₂ <;> simp [h₄]
case none => exact type_is_inhabited CedarType.int
case some => simp [InstanceOfType.instance_of_int]
case inr.inr =>
cases h₄ : Int64.mul? i₁ i₂ <;> simp [h₄]
case none => exact type_is_inhabited CedarType.int
case some => simp [InstanceOfType.instance_of_int]

theorem type_of_contains_inversion {x₁ x₂ : Expr} {c c' : Capabilities} {env : Environment} {ty : CedarType}
(h₁ : typeOf (Expr.binaryApp .contains x₁ x₂) c env = Except.ok (ty, c')) :
Expand Down Expand Up @@ -838,7 +842,8 @@ theorem type_of_binaryApp_is_sound {op₂ : BinaryOp} {x₁ x₂ : Expr} {c₁ c
| .less
| .lessEq => exact type_of_int_cmp_is_sound (by simp) h₁ h₂ h₃ ih₁ ih₂
| .add
| .sub => exact type_of_int_arith_is_sound (by simp) h₁ h₂ h₃ ih₁ ih₂
| .sub
| .mul => exact type_of_int_arith_is_sound (by simp) h₁ h₂ h₃ ih₁ ih₂
| .contains => exact type_of_contains_is_sound h₁ h₂ h₃ ih₁ ih₂
| .containsAll
| .containsAny => exact type_of_containsA_is_sound (by simp) h₁ h₂ h₃ ih₁ ih₂
Expand Down
50 changes: 1 addition & 49 deletions cedar-lean/Cedar/Thm/Validation/Typechecker/UnaryApp.lean
Original file line number Diff line number Diff line change
Expand Up @@ -133,53 +133,6 @@ theorem type_of_neg_is_sound {x₁ : Expr} {c₁ c₂ : Capabilities} {env : Env
exact type_is_inhabited CedarType.int
}

theorem type_of_mulBy_inversion {x₁ : Expr} {k : Int64} {c₁ c₂ : Capabilities} {env : Environment} {ty : CedarType}
(h₁ : typeOf (Expr.unaryApp (.mulBy k) x₁) c₁ env = Except.ok (ty, c₂)) :
c₂ = ∅ ∧
ty = .int ∧
∃ c₁', typeOf x₁ c₁ env = Except.ok (.int, c₁')
:= by
simp [typeOf] at h₁
cases h₂ : typeOf x₁ c₁ env <;> simp [h₂] at h₁
case ok res =>
have ⟨ty₁, c₁'⟩ := res
simp [typeOfUnaryApp] at h₁
split at h₁ <;> try contradiction
simp [ok] at h₁
simp [h₁]

theorem type_of_mulBy_is_sound {x₁ : Expr} {k : Int64} {c₁ c₂ : Capabilities} {env : Environment} {ty : CedarType} {request : Request} {entities : Entities}
(h₁ : CapabilitiesInvariant c₁ request entities)
(h₂ : RequestAndEntitiesMatchEnvironment env request entities)
(h₃ : typeOf (Expr.unaryApp (.mulBy k) x₁) c₁ env = Except.ok (ty, c₂))
(ih : TypeOfIsSound x₁) :
GuardedCapabilitiesInvariant (Expr.unaryApp (.mulBy k) x₁) c₂ request entities ∧
∃ v, EvaluatesTo (Expr.unaryApp (.mulBy k) x₁) request entities v ∧ InstanceOfType v ty
:= by
have ⟨h₅, h₆, c₁', h₄⟩ := type_of_mulBy_inversion h₃
subst h₅; subst h₆
apply And.intro
case left => exact empty_guarded_capabilities_invariant
case right =>
have ⟨_, v₁, h₆, h₇⟩ := ih h₁ h₂ h₄ -- IH
simp [EvaluatesTo] at h₆
simp [EvaluatesTo, evaluate]
rcases h₆ with h₆ | h₆ | h₆ | h₆ <;> simp [h₆]
case inr.inr.inr =>
have ⟨i, h₈⟩ := instance_of_int_is_int h₇
subst h₈
simp [apply₁, intOrErr]
cases h₉ : k.mul? i
case none =>
simp only [or_false, or_true, true_and]
exact type_is_inhabited CedarType.int
case some i' =>
simp only [Except.ok.injEq, false_or, exists_eq_left']
apply InstanceOfType.instance_of_int
all_goals {
exact type_is_inhabited CedarType.int
}

theorem type_of_like_inversion {x₁ : Expr} {p : Pattern} {c₁ c₂ : Capabilities} {env : Environment} {ty : CedarType}
(h₁ : typeOf (Expr.unaryApp (.like p) x₁) c₁ env = Except.ok (ty, c₂)) :
c₂ = ∅ ∧
Expand Down Expand Up @@ -234,7 +187,7 @@ theorem type_of_is_inversion {x₁ : Expr} {ety : EntityType} {c₁ c₂ : Capab
have ⟨ty₁, c₁'⟩ := res
simp [typeOfUnaryApp] at h₁
split at h₁ <;> try contradiction
case h_5 _ _ ety' h₃ =>
case h_4 _ _ ety' h₃ =>
simp only [UnaryOp.is.injEq] at h₃
subst h₃
simp [ok] at h₁
Expand Down Expand Up @@ -284,7 +237,6 @@ theorem type_of_unaryApp_is_sound {op₁ : UnaryOp} {x₁ : Expr} {c₁ c₂ : C
match op₁ with
| .not => exact type_of_not_is_sound h₁ h₂ h₃ ih
| .neg => exact type_of_neg_is_sound h₁ h₂ h₃ ih
| .mulBy k => exact type_of_mulBy_is_sound h₁ h₂ h₃ ih
| .like p => exact type_of_like_is_sound h₁ h₂ h₃ ih
| .is ety => exact type_of_is_is_sound h₁ h₂ h₃ ih

Expand Down
2 changes: 1 addition & 1 deletion cedar-lean/Cedar/Validation/Typechecker.lean
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ def typeOfUnaryApp (op : UnaryOp) (ty : CedarType) : ResultType :=
match op, ty with
| .not, .bool x => ok (.bool x.not)
| .neg, .int => ok .int
| .mulBy _, .int => ok .int
| .like _, .string => ok (.bool .anyBool)
| .is ety₁, .entity ety₂ => ok (.bool (if ety₁ = ety₂ then .tt else .ff))
| _, _ => err (.unexpectedType ty)
Expand Down Expand Up @@ -172,6 +171,7 @@ def typeOfBinaryApp (op₂ : BinaryOp) (ty₁ ty₂ : CedarType) (x₁ x₂ : Ex
| .lessEq, .int, .int => ok (.bool .anyBool)
| .add, .int, .int => ok .int
| .sub, .int, .int => ok .int
| .mul, .int, .int => ok .int
| .contains, .set ty₃, _ => ifLubThenBool ty₂ ty₃
| .containsAll, .set ty₃, .set ty₄ => ifLubThenBool ty₃ ty₄
| .containsAny, .set ty₃, .set ty₄ => ifLubThenBool ty₃ ty₄
Expand Down
5 changes: 1 addition & 4 deletions cedar-lean/DiffTest/Parser.lean
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def jsonToBinaryOp (json : Lean.Json) : ParseResult BinaryOp := do
| "LessEq" => .ok .lessEq
| "Add" => .ok .add
| "Sub" => .ok .sub
| "Mul" => .ok .mul
| "Contains" => .ok .contains
| "ContainsAll" => .ok .containsAll
| "ContainsAny" => .ok .containsAny
Expand Down Expand Up @@ -181,10 +182,6 @@ partial def jsonToExpr (json : Lean.Json) : ParseResult Expr := do
let op ← getJsonField body "op" >>= jsonToUnaryOp
let arg ← getJsonField body "arg" >>= jsonToExpr
.ok (.unaryApp op arg)
| "MulByConst" => do
let c ← getJsonField body "constant" >>= jsonToInt64
let arg ← getJsonField body "arg" >>= jsonToExpr
.ok (.unaryApp (.mulBy c) arg)
| "Like" => do
let pat ← getJsonField body "pattern" >>= jsonToPattern
let expr ← getJsonField body "expr" >>= jsonToExpr
Expand Down
28 changes: 13 additions & 15 deletions cedar-policy-generators/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,10 @@ impl<'a> ExprGenerator<'a> {
self.generate_expr(max_depth - 1, u)?,
self.generate_expr(max_depth - 1, u)?,
)),
1 => {
// arbitrary expression, which may be a constant
let expr = self.generate_expr(max_depth - 1, u)?;
// arbitrary constant integer
let c = self.constant_pool.arbitrary_int_constant(u)?;
Ok(ast::Expr::mul(expr, c))
},
1 => Ok(ast::Expr::mul(
self.generate_expr(max_depth - 1, u)?,
self.generate_expr(max_depth - 1, u)?,
)),
1 => {
// negation expression
Ok(ast::Expr::neg(self.generate_expr(max_depth - 1, u)?))
Expand Down Expand Up @@ -641,17 +638,18 @@ impl<'a> ExprGenerator<'a> {
)?,
)),
// * expression
1 => {
// arbitrary expression, which may be a constant
let expr = self.generate_expr_for_type(
1 => Ok(ast::Expr::mul(
self.generate_expr_for_type(
&Type::long(),
max_depth - 1,
u,
)?;
// arbitrary integer constant
let c = self.constant_pool.arbitrary_int_constant(u)?;
Ok(ast::Expr::mul(expr, c))
},
)?,
self.generate_expr_for_type(
&Type::long(),
max_depth - 1,
u,
)?,
)),
// negation expression
1 => Ok(ast::Expr::neg(self.generate_expr_for_type(
&Type::long(),
Expand Down