summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-12-30 10:01:37 +0100
committerLaurenz <laurmaedje@gmail.com>2022-12-30 10:01:37 +0100
commit94cf7005e99a9055799a641ae6f00669c5ec7a63 (patch)
tree463e262e86348f0cf04295dd4dcc83fba6f4a4ea
parent68c6160a14be4e77b98cd704d9e641a03aefa332 (diff)
Forbid division by zero
-rw-r--r--src/model/ops.rs21
-rw-r--r--tests/typ/compiler/ops-invalid.typ12
2 files changed, 32 insertions, 1 deletions
diff --git a/src/model/ops.rs b/src/model/ops.rs
index 9da9b0cc..7acf917d 100644
--- a/src/model/ops.rs
+++ b/src/model/ops.rs
@@ -1,10 +1,11 @@
//! Operations on values.
+use std::cmp::Ordering;
+
use super::{Regex, Value};
use crate::diag::StrResult;
use crate::geom::{Axes, Axis, GenAlign, Length, Numeric, PartialStroke, Rel, Smart};
use crate::util::format_eco;
-use std::cmp::Ordering;
use Value::*;
/// Bail with a type mismatch error.
@@ -195,6 +196,10 @@ pub fn mul(lhs: Value, rhs: Value) -> StrResult<Value> {
/// Compute the quotient of two values.
pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> {
+ if is_zero(&rhs) {
+ Err("cannot divide by zero")?;
+ }
+
Ok(match (lhs, rhs) {
(Int(a), Int(b)) => Float(a as f64 / b as f64),
(Int(a), Float(b)) => Float(a as f64 / b),
@@ -229,6 +234,20 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> {
})
}
+/// Whether a value is a numeric zero.
+fn is_zero(v: &Value) -> bool {
+ match *v {
+ Int(v) => v == 0,
+ Float(v) => v == 0.0,
+ Length(v) => v.is_zero(),
+ Angle(v) => v.is_zero(),
+ Ratio(v) => v.is_zero(),
+ Relative(v) => v.is_zero(),
+ Fraction(v) => v.is_zero(),
+ _ => false,
+ }
+}
+
/// Try to divide two lengths.
fn try_div_length(a: Length, b: Length) -> StrResult<f64> {
a.try_div(b).ok_or_else(|| "cannot divide these two lengths".into())
diff --git a/tests/typ/compiler/ops-invalid.typ b/tests/typ/compiler/ops-invalid.typ
index 3e9e5478..3d41a3d1 100644
--- a/tests/typ/compiler/ops-invalid.typ
+++ b/tests/typ/compiler/ops-invalid.typ
@@ -34,6 +34,18 @@
{1em <= 10pt}
---
+// Error: 2-11 cannot divide by zero
+{1.2 / 0.0}
+
+---
+// Error: 2-7 cannot divide by zero
+{1 / 0}
+
+---
+// Error: 2-14 cannot divide by zero
+{15deg / 0deg}
+
+---
// Special messages for +, -, * and /.
// Error: 03-10 cannot add integer and string
{(1 + "2", 40% - 1)}