From 38272bf85341348eb0a5162ba4e1c95d370f9bce Mon Sep 17 00:00:00 2001 From: Ben Wagner Date: Mon, 16 Dec 2024 14:29:36 -0500 Subject: [PATCH] [ftstroke] Fix invalid pointer assignement to `arc` In `FT_Stroker_ConicTo` and `FT_Stroker_CubicTo` there is a `bez_stack`. `arc` is initialized with `arc = bez_stack` and is never set to point into any different object. The main loop looks like `while ( arc >= bez_stack )` which is depending on a later `arc -= 2` (or `arc -= 3`) to make `arc` point to before `bez_stack`. However, using pointer subtraction to make `arc` point outside the array is undefined behavior, and attempting to use the value in the loop predicate is "very" undefined behavior. (C99 "Additive operators" 6.5.6.8.) This particular undefined behavior was discovered as either hangs or MemorySantizer issues after "[InstCombine] Infer nuw for gep inbounds from base of object" [0]. With this change, clang can infer that `arc` must always point into the `bez_stack` object and therefore cannot be at a "negative index" so the predicate is always true. [0] https://github.com/llvm/llvm-project/commit/e21ab4d16b555c28ded307571d138f594f33e325 * src/base/ftstroke.c (FT_Stroker_ConicTo, FT_Stroker_CubicTo): test loop exit condition (there are no more arcs to process) before decrementing `arc` Fixes: #1307 --- src/base/ftstroke.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c index 64f46ce43..40d74d6e4 100644 --- a/src/base/ftstroke.c +++ b/src/base/ftstroke.c @@ -1371,7 +1371,7 @@ arc[1] = *control; arc[2] = stroker->center; - while ( arc >= bez_stack ) + do { FT_Angle angle_in, angle_out; @@ -1524,10 +1524,12 @@ } } - arc -= 2; - stroker->angle_in = angle_out; - } + + if ( arc == bez_stack ) + break; + arc -= 2; + } while ( 1 ); stroker->center = *to; stroker->line_length = 0; @@ -1577,7 +1579,7 @@ arc[2] = *control1; arc[3] = stroker->center; - while ( arc >= bez_stack ) + do { FT_Angle angle_in, angle_mid, angle_out; @@ -1741,10 +1743,12 @@ } } - arc -= 3; - stroker->angle_in = angle_out; - } + + if ( arc == bez_stack ) + break; + arc -= 3; + } while ( 1 ); stroker->center = *to; stroker->line_length = 0;