difftreelog
feat(evaluator) number overflow checks
in: master
2 files changed
crates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate.rs
@@ -92,7 +92,7 @@
(Val::Obj(v1), Val::Obj(v2)) => Val::Obj(v2.with_super(v1.clone())),
(Val::Arr(a), Val::Arr(b)) => Val::Arr(Rc::new([&a[..], &b[..]].concat())),
- (Val::Num(v1), Val::Num(v2)) => Val::Num(v1 + v2),
+ (Val::Num(v1), Val::Num(v2)) => Val::new_checked_num(v1 + v2)?,
_ => create_error_result(Error::BinaryOperatorDoesNotOperateOnValues(
BinaryOpType::Add,
a.value_type()?,
@@ -135,15 +135,15 @@
(Val::Str(v1), BinaryOpType::Gte, Val::Str(v2)) => Val::Bool(v1 >= v2),
// Num X Num
- (Val::Num(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Num(v1 * v2),
+ (Val::Num(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::new_checked_num(v1 * v2)?,
(Val::Num(v1), BinaryOpType::Div, Val::Num(v2)) => {
if *v2 <= f64::EPSILON {
create_error_result(crate::Error::DivisionByZero)?
}
- Val::Num(v1 / v2)
+ Val::new_checked_num(v1 / v2)?
}
- (Val::Num(v1), BinaryOpType::Sub, Val::Num(v2)) => Val::Num(v1 - v2),
+ (Val::Num(v1), BinaryOpType::Sub, Val::Num(v2)) => Val::new_checked_num(v1 - v2)?,
(Val::Num(v1), BinaryOpType::Lt, Val::Num(v2)) => Val::Bool(v1 < v2),
(Val::Num(v1), BinaryOpType::Gt, Val::Num(v2)) => Val::Bool(v1 > v2),
@@ -644,7 +644,7 @@
Literal(LiteralType::Null) => Val::Null,
Parened(e) => evaluate(context, e)?,
Str(v) => Val::Str(v.clone()),
- Num(v) => Val::Num(*v),
+ Num(v) => Val::new_checked_num(*v)?,
BinaryOp(v1, o, v2) => evaluate_binary_op_special(context, &v1, *o, &v2)?,
UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(context, v)?)?,
Var(name) => push(loc, "var", || {
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth134 };134 };135}135}136impl Val {136impl Val {137 /// Creates Val::Num after checking for overflow. As numbers are f64, we can just check for finity138 pub fn new_checked_num(num: f64) -> Result<Val> {139 if num.is_finite() {140 Ok(Val::Num(num))141 } else {142 create_error_result(Error::RuntimeError("overflow".into()))143 }144 }145137 pub fn assert_type(&self, context: &'static str, val_type: ValType) -> Result<()> {146 pub fn assert_type(&self, context: &'static str, val_type: ValType) -> Result<()> {138 let this_type = self.value_type()?;147 let this_type = self.value_type()?;