[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] e21ab4d16b

* 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
master
Ben Wagner 2 weeks ago
parent 59320b2d3c
commit 38272bf853
  1. 20
      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;

Loading…
Cancel
Save