From cfaad8ab623bc6aee6e4d713d6b1ffe49438d48b Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 5 Feb 2023 20:22:26 +0100 Subject: draw_linear_bezier_reference: fix bounds checking error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- common.h | 1 + draw_linear_bezier_reference.c | 68 +++++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/common.h b/common.h index 67a1c62..805ba0b 100644 --- a/common.h +++ b/common.h @@ -123,6 +123,7 @@ PURE_FUNCTION int doublepcmp(const void *avp, const void *bvp); #ifdef TEST +#include #if defined(__GNUC__) && !defined(__clang__) # pragma GCC diagnostic ignored "-Wunsuffixed-float-constants" diff --git a/draw_linear_bezier_reference.c b/draw_linear_bezier_reference.c index c288781..451eb3a 100644 --- a/draw_linear_bezier_reference.c +++ b/draw_linear_bezier_reference.c @@ -56,10 +56,11 @@ draw_linear_bezier_reference(RASTER *restrict raster, double x1, double y1, doub x = cx; /* Make sure loop will exit when we reach the end */ - if ((xdir < 0 && x < x2) || (xdir > 0 && x > x2)) + if ((xdir < 0 && x <= x2) || (xdir > 0 && x >= x2) || + (ydir < 0 && y <= y2) || (ydir > 0 && y >= y2)) { x = x2; - if ((ydir < 0 && y < y2) || (ydir > 0 && y > y2)) y = y2; + } } /* Select cell to draw in */ @@ -152,6 +153,17 @@ print_raster(void) #endif +static void +draw(double x1, double y1, double x2, double y2) +{ + alarm(5); + draw_linear_bezier_reference(raster, x1, y1, x2, y2); + alarm(0); +} +#undef draw_linear_bezier_reference +#define draw_linear_bezier_reference "use draw(double, double, double, double) instead" + + static void check_horizontal(void) { @@ -160,16 +172,16 @@ check_horizontal(void) for (y = -2; y < 12; y++) { for (x1 = -2; x1 < 12; x1++) { for (x2 = -2; x2 < 12; x2++) { - draw_linear_bezier_reference(raster, x1, y, x2, y); + draw(x1, y, x2, y); CHECK_ZEROED(); - draw_linear_bezier_reference(raster, x1 + 0.25, y, x2 + 0.25, y); + draw(x1 + 0.25, y, x2 + 0.25, y); CHECK_ZEROED(); - draw_linear_bezier_reference(raster, x1, y + 0.25, x2, y + 0.25); + draw(x1, y + 0.25, x2, y + 0.25); CHECK_ZEROED(); - draw_linear_bezier_reference(raster, x1 + 0.25, y + 0.25, x2 + 0.25, y + 0.25); + draw(x1 + 0.25, y + 0.25, x2 + 0.25, y + 0.25); CHECK_ZEROED(); } } @@ -188,7 +200,7 @@ check_vertical(void) for (y2 = -2; y2 < 12; y2++) { ydir = SIGNUM(y2 - y1); - draw_linear_bezier_reference(raster, x, y1, x, y2); + draw(x, y1, x, y2); for (i = 0; i < 10; i++) { if (i < y1 && i < y2) continue; @@ -201,7 +213,7 @@ check_vertical(void) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, x + 0.25, y1, x + 0.25, y2); + draw(x + 0.25, y1, x + 0.25, y2); for (i = 0; i < 10; i++) { if (i < y1 && i < y2) continue; @@ -214,7 +226,7 @@ check_vertical(void) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, x, y1 + 0.25, x, y2 + 0.25); + draw(x, y1 + 0.25, x, y2 + 0.25); for (i = 0; i < 10; i++) { if (i < y1 + (y1 > y2) && i < y2 + (y2 > y1)) continue; @@ -228,7 +240,7 @@ check_vertical(void) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, x + 0.25, y1 + 0.25, x + 0.25, y2 + 0.25); + draw(x + 0.25, y1 + 0.25, x + 0.25, y2 + 0.25); for (i = 0; i < 10; i++) { if (i < y1 + (y1 > y2) && i < y2 + (y2 > y1)) continue; @@ -258,7 +270,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift) imax = i1 > i2 ? i1 : i2; idir = SIGNUM(i2 - i1); - draw_linear_bezier_reference(raster, i1 + xshift, i1 + yshift, i2 + xshift, i2 + yshift); + draw(i1 + xshift, i1 + yshift, i2 + xshift, i2 + yshift); for (i = imin; i < imax; i++) { x = i + xshift; y = i + yshift; @@ -273,7 +285,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, i1 + xshift, i1 + yshift + 0.25, i2 + xshift, i2 + yshift + 0.25); + draw(i1 + xshift, i1 + yshift + 0.25, i2 + xshift, i2 + yshift + 0.25); for (i = imin; i < imax; i++) { x = i + xshift; y = i + yshift; @@ -298,7 +310,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i1 + yshift, i2 + xshift + 0.25, i2 + yshift); + draw(i1 + xshift + 0.25, i1 + yshift, i2 + xshift + 0.25, i2 + yshift); for (i = imin; i < imax; i++) { x = i + xshift; y = i + yshift; @@ -323,8 +335,7 @@ check_11_diagonal(ssize_t xshift, ssize_t yshift) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i1 + yshift + 0.25, - i2 + xshift + 0.25, i2 + yshift + 0.25); + draw(i1 + xshift + 0.25, i1 + yshift + 0.25, i2 + xshift + 0.25, i2 + yshift + 0.25); for (i = imin; i < imax; i++) { x = i + xshift; y = i + yshift; @@ -364,7 +375,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift) imax = i1 > i2 ? i1 : i2; ydir = -SIGNUM(i2 - i1); - draw_linear_bezier_reference(raster, i1 + xshift, i2 + yshift, i2 + xshift, i1 + yshift); + draw(i1 + xshift, i2 + yshift, i2 + xshift, i1 + yshift); for (i = imin; i < imax; i++) { x = i + xshift; y = imax - i + imin + yshift - 1; @@ -379,7 +390,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, i1 + xshift, i2 + yshift + 0.25, i2 + xshift, i1 + yshift + 0.25); + draw(i1 + xshift, i2 + yshift + 0.25, i2 + xshift, i1 + yshift + 0.25); for (i = imin; i < imax; i++) { x = i + xshift; y = imax - i + imin + yshift - 1; @@ -404,7 +415,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i2 + yshift, i2 + xshift + 0.25, i1 + yshift); + draw(i1 + xshift + 0.25, i2 + yshift, i2 + xshift + 0.25, i1 + yshift); for (i = imin; i < imax; i++) { x = i + xshift; y = imax - i + imin + yshift - 1; @@ -429,8 +440,7 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift) } CHECK_ZEROED(); - draw_linear_bezier_reference(raster, i1 + xshift + 0.25, i2 + yshift + 0.25, - i2 + xshift + 0.25, i1 + yshift + 0.25); + draw(i1 + xshift + 0.25, i2 + yshift + 0.25, i2 + xshift + 0.25, i1 + yshift + 0.25); for (i = imin; i < imax; i++) { x = i + xshift; y = imax - i + imin + yshift - 1; @@ -469,11 +479,25 @@ check_11_antidiagonal(ssize_t xshift, ssize_t yshift) } +static void +try_random_line(void) +{ + double x1 = (double)rand() / (double)RAND_MAX; + double y1 = (double)rand() / (double)RAND_MAX; + double x2 = (double)rand() / (double)RAND_MAX; + double y2 = (double)rand() / (double)RAND_MAX; + draw(x1, y1, x2, y2); +} + + int main(void) { + size_t i; + raster = rtgrpblib_create_raster(10, 10); ASSERT(raster); + srand((unsigned)(uintptr_t)raster); check_horizontal(); check_vertical(); @@ -498,6 +522,10 @@ main(void) check_11_antidiagonal(-2, 2); check_11_antidiagonal(-2, -2); + for (i = 0; i < 100000UL; i++) + try_random_line(); + rtgrpblib_reset_raster(raster, 10, 10); + free(raster); return 0; } -- cgit v1.2.3-70-g09d2