aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2016-10-09 20:57:55 -0400
committerKevin O'Connor <kevin@koconnor.net>2016-10-10 11:39:26 -0400
commitab54fcd44381a9d5d9a524784760c65b0e789d7b (patch)
treee8acb2be7c622bea98dea91ce8fe5a895f705fc6
parent9fa0a62c8a0990178aa2f0485d48ee7aaf975e7a (diff)
downloadkutter-ab54fcd44381a9d5d9a524784760c65b0e789d7b.tar.gz
kutter-ab54fcd44381a9d5d9a524784760c65b0e789d7b.tar.xz
kutter-ab54fcd44381a9d5d9a524784760c65b0e789d7b.zip
stepcompress: Check for small negative numbers on sqrt() calls
It's theoretically possible for floating point truncation to cause a math formula to return a small negative number instead of 0. If sqrt() is called on this small negative number it could cause a crash. Check for this case and return 0. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--klippy/stepcompress.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/klippy/stepcompress.c b/klippy/stepcompress.c
index 55cb09e8..be431e20 100644
--- a/klippy/stepcompress.c
+++ b/klippy/stepcompress.c
@@ -249,6 +249,17 @@ check_line(struct stepcompress *sc, struct step_move move)
* Step compress interface
****************************************************************/
+// Wrapper around sqrt() to handle small negative numbers
+static inline double
+safe_sqrt(double v)
+{
+ if (v < 0. && v > -0.001)
+ // Due to floating point truncation, it's possible to get a
+ // small negative number - treat it as zero.
+ return 0.;
+ return sqrt(v);
+}
+
// Allocate a new 'stepcompress' object
struct stepcompress *
stepcompress_alloc(uint32_t max_error, uint32_t queue_step_msgid, uint32_t oid)
@@ -325,12 +336,12 @@ stepcompress_push_sqrt(struct stepcompress *sc, double steps, double step_offset
double pos = step_offset + sqrt_offset/factor;
if (factor >= 0.0)
while (qn < end) {
- *qn++ = clock_offset + sqrt(pos*factor);
+ *qn++ = clock_offset + safe_sqrt(pos*factor);
pos += 1.0;
}
else
while (qn < end) {
- *qn++ = clock_offset - sqrt(pos*factor);
+ *qn++ = clock_offset - safe_sqrt(pos*factor);
pos += 1.0;
}
sc->queue_next = qn;