[psaux] Fix assertions.

* src/psaux/pshints.c (cf2_hintmap_adjustHints): Check for overflow
before emitting an assertion error.
This commit is contained in:
Werner Lemberg 2021-06-12 08:40:16 +02:00
parent 9bfecfd2b6
commit a34afe6786
2 changed files with 33 additions and 19 deletions

View File

@ -1,3 +1,10 @@
2021-06-12 Werner Lemberg <wl@gnu.org>
[psaux] Fix assertions.
* src/psaux/pshints.c (cf2_hintmap_adjustHints): Check for overflow
before emitting an assertion error.
2021-06-09 Alexei Podtelezhnikov <apodtele@gmail.com> 2021-06-09 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/truetype/ttinterp.c (TT_RunIns): Optimize tracing. * src/truetype/ttinterp.c (TT_RunIns): Optimize tracing.

View File

@ -412,6 +412,12 @@
{ {
FT_Bool isPair = cf2_hint_isPair( &hintmap->edge[i] ); FT_Bool isPair = cf2_hint_isPair( &hintmap->edge[i] );
/* final amount to move edge or edge pair */
CF2_Fixed move = 0;
CF2_Fixed dsCoord_i;
CF2_Fixed dsCoord_j;
/* index of upper edge (same value for ghost hint) */ /* index of upper edge (same value for ghost hint) */
j = isPair ? i + 1 : i; j = isPair ? i + 1 : i;
@ -422,11 +428,14 @@
FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) == FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) ==
cf2_hint_isLocked( &hintmap->edge[j] ) ); cf2_hint_isLocked( &hintmap->edge[j] ) );
dsCoord_i = hintmap->edge[i].dsCoord;
dsCoord_j = hintmap->edge[j].dsCoord;
if ( !cf2_hint_isLocked( &hintmap->edge[i] ) ) if ( !cf2_hint_isLocked( &hintmap->edge[i] ) )
{ {
/* hint edge is not locked, we can adjust it */ /* hint edge is not locked, we can adjust it */
CF2_Fixed fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord ); CF2_Fixed fracDown = cf2_fixedFraction( dsCoord_i );
CF2_Fixed fracUp = cf2_fixedFraction( hintmap->edge[j].dsCoord ); CF2_Fixed fracUp = cf2_fixedFraction( dsCoord_j );
/* calculate all four possibilities; moves down are negative */ /* calculate all four possibilities; moves down are negative */
CF2_Fixed downMoveDown = 0 - fracDown; CF2_Fixed downMoveDown = 0 - fracDown;
@ -443,9 +452,6 @@
/* smallest move down */ /* smallest move down */
CF2_Fixed moveDown = FT_MAX( downMoveDown, upMoveDown ); CF2_Fixed moveDown = FT_MAX( downMoveDown, upMoveDown );
/* final amount to move edge or edge pair */
CF2_Fixed move;
CF2_Fixed downMinCounter = CF2_MIN_COUNTER; CF2_Fixed downMinCounter = CF2_MIN_COUNTER;
CF2_Fixed upMinCounter = CF2_MIN_COUNTER; CF2_Fixed upMinCounter = CF2_MIN_COUNTER;
FT_Bool saveEdge = FALSE; FT_Bool saveEdge = FALSE;
@ -467,16 +473,14 @@
/* is there room to move up? */ /* is there room to move up? */
/* there is if we are at top of array or the next edge is at or */ /* there is if we are at top of array or the next edge is at or */
/* beyond proposed move up? */ /* beyond proposed move up? */
if ( j >= hintmap->count - 1 || if ( j >= hintmap->count - 1 ||
hintmap->edge[j + 1].dsCoord >= hintmap->edge[j + 1].dsCoord >=
ADD_INT32( hintmap->edge[j].dsCoord, ADD_INT32( dsCoord_j, moveUp + upMinCounter ) )
moveUp + upMinCounter ) )
{ {
/* there is room to move up; is there also room to move down? */ /* there is room to move up; is there also room to move down? */
if ( i == 0 || if ( i == 0 ||
hintmap->edge[i - 1].dsCoord <= hintmap->edge[i - 1].dsCoord <=
ADD_INT32( hintmap->edge[i].dsCoord, ADD_INT32( dsCoord_i, moveDown - downMinCounter ) )
moveDown - downMinCounter ) )
{ {
/* move smaller absolute amount */ /* move smaller absolute amount */
move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */ move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */
@ -487,10 +491,9 @@
else else
{ {
/* is there room to move down? */ /* is there room to move down? */
if ( i == 0 || if ( i == 0 ||
hintmap->edge[i - 1].dsCoord <= hintmap->edge[i - 1].dsCoord <=
ADD_INT32( hintmap->edge[i].dsCoord, ADD_INT32( dsCoord_i, moveDown - downMinCounter ) )
moveDown - downMinCounter ) )
{ {
move = moveDown; move = moveDown;
/* true if non-optimum move */ /* true if non-optimum move */
@ -524,17 +527,21 @@
} }
/* move the edge(s) */ /* move the edge(s) */
hintmap->edge[i].dsCoord = ADD_INT32( hintmap->edge[i].dsCoord, hintmap->edge[i].dsCoord = ADD_INT32( dsCoord_i, move );
move );
if ( isPair ) if ( isPair )
hintmap->edge[j].dsCoord = ADD_INT32( hintmap->edge[j].dsCoord, hintmap->edge[j].dsCoord = ADD_INT32( dsCoord_j, move );
move );
} }
/* assert there are no overlaps in device space */ /* assert there are no overlaps in device space; */
/* ignore tests if there was overflow (that is, if */
/* operands have the same sign but the sum does not) */
FT_ASSERT( i == 0 || FT_ASSERT( i == 0 ||
( ( dsCoord_i ^ move ) >= 0 &&
( dsCoord_i ^ hintmap->edge[i].dsCoord ) < 0 ) ||
hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord ); hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord );
FT_ASSERT( i < j || FT_ASSERT( i < j ||
( ( dsCoord_j ^ move ) >= 0 &&
( dsCoord_j ^ hintmap->edge[j].dsCoord ) < 0 ) ||
hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord ); hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord );
/* adjust the scales, avoiding divide by zero */ /* adjust the scales, avoiding divide by zero */