feat(tvix/eval): detect division by zero
This detects if the second argument of a division is a zero (either as integer or as float). If so, an error message is displayed. This fixes b/219. Change-Id: I50203d14a71482bc757832a2c8dee08eb7d35c49 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7258 Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
parent
40826e664d
commit
d00030128e
4 changed files with 22 additions and 1 deletions
|
@ -20,6 +20,8 @@ pub enum ErrorKind {
|
|||
Abort(String),
|
||||
AssertionFailed,
|
||||
|
||||
DivisionByZero,
|
||||
|
||||
DuplicateAttrsKey {
|
||||
key: String,
|
||||
},
|
||||
|
@ -215,6 +217,8 @@ impl Display for Error {
|
|||
ErrorKind::Abort(msg) => write!(f, "evaluation aborted: {}", msg),
|
||||
ErrorKind::AssertionFailed => write!(f, "assertion failed"),
|
||||
|
||||
ErrorKind::DivisionByZero => write!(f, "division by zero"),
|
||||
|
||||
ErrorKind::DuplicateAttrsKey { key } => {
|
||||
write!(f, "attribute key '{}' already defined", key)
|
||||
}
|
||||
|
@ -656,6 +660,7 @@ impl Error {
|
|||
| ErrorKind::TailEmptyList
|
||||
| ErrorKind::TypeError { .. }
|
||||
| ErrorKind::Incomparable { .. }
|
||||
| ErrorKind::DivisionByZero
|
||||
| ErrorKind::DynamicKeyInScope(_)
|
||||
| ErrorKind::UnknownStaticVariable
|
||||
| ErrorKind::UnknownDynamicVariable(_)
|
||||
|
@ -717,6 +722,7 @@ impl Error {
|
|||
ErrorKind::FromJsonError { .. } => "E030",
|
||||
ErrorKind::UnexpectedArgument { .. } => "E031",
|
||||
ErrorKind::RelativePathResolution(_) => "E032",
|
||||
ErrorKind::DivisionByZero => "E033",
|
||||
|
||||
// Special error code that is not part of the normal
|
||||
// ordering.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1.0 / 0.0
|
|
@ -0,0 +1 @@
|
|||
1 / 0
|
|
@ -412,7 +412,20 @@ impl<'o> VM<'o> {
|
|||
|
||||
OpCode::OpSub => arithmetic_op!(self, -),
|
||||
OpCode::OpMul => arithmetic_op!(self, *),
|
||||
OpCode::OpDiv => arithmetic_op!(self, /),
|
||||
OpCode::OpDiv => {
|
||||
let b = self.peek(0);
|
||||
|
||||
match b {
|
||||
Value::Integer(0) => return Err(self.error(ErrorKind::DivisionByZero)),
|
||||
Value::Float(b) => {
|
||||
if *b == (0.0 as f64) {
|
||||
return Err(self.error(ErrorKind::DivisionByZero));
|
||||
}
|
||||
arithmetic_op!(self, /)
|
||||
}
|
||||
_ => arithmetic_op!(self, /),
|
||||
};
|
||||
}
|
||||
|
||||
OpCode::OpInvert => {
|
||||
let v = fallible!(self, self.pop().as_bool());
|
||||
|
|
Loading…
Reference in a new issue