From cd10e5557dfa1bcba33694501be68867d99f6e77 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 7 Jun 2025 20:58:50 -0400 Subject: [PATCH] src/svgtiny_gradient.c: be more careful with float -> int assignment 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 +#include #include #include #include @@ -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