Assigning the value of a float to an unsigned int is undefined
behavior unless the value is guaranteed to fit. We run afoul of this
in compute_grad_points(), where the number of steps is computed using
a floating point calculation.
On a RISC-V / musl system, the end result is that we wind up with
steps = the maximum value of an unsigned int, when really this should
be an error case resulting in steps = 1. The test suite catches this.
---
src/svgtiny_gradient.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/svgtiny_gradient.c b/src/svgtiny_gradient.c
index ca961cc..8fd0f83 100644
--- a/src/svgtiny_gradient.c
+++ b/src/svgtiny_gradient.c
@@ -6,6 +6,7 @@
*/
#include <assert.h>
+#include <limits.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
@@ -427,7 +428,18 @@ compute_grad_points(float *p,
if(isnan(r0) || isnan(r1)) {
steps = 1;
} else {
- steps = ceilf(fabsf(r1 - r0) / 0.05);
+ /* float -> int assignment is undefined unless
+ * the value is guaranteed to fit */
+ float stepsf = ceilf(fabsf(r1 - r0) / 0.05);
+ if (isnan(stepsf)) {
+ steps = 1;
+ }
+ else if (stepsf > (float)UINT_MAX) {
+ steps = 1;
+ }
+ else {
+ steps = stepsf;
+ }
}
if (steps == 0)
--
2.49.0
No comments:
Post a Comment