[base] Tighten the overflow check in `FT_DivFix'.

This fixes a 13-year old bug. The original overflow check should have
been updated when rounding was introduced into this function
(c2cd00443b).

* src/base/ftcalc.c (FT_DivFix) [!FT_LONG64]: Updated.
* include/freetype.h (FT_DivFix): Updated documentation.
This commit is contained in:
Alexei Podtelezhnikov 2014-09-03 22:55:26 -04:00
parent 3212852cce
commit 336735d8de
3 changed files with 21 additions and 9 deletions

View File

@ -1,3 +1,14 @@
2014-09-03 Alexei Podtelezhnikov <apodtele@gmail.com>
[base] Tighten the overflow check in `FT_DivFix'.
This fixes a 13-year old bug. The original overflow check should have
been updated when rounding was introduced into this function
(c2cd00443b).
* src/base/ftcalc.c (FT_DivFix) [!FT_LONG64]: Updated.
* include/freetype.h (FT_DivFix): Updated documentation.
2014-09-03 Alexei Podtelezhnikov <apodtele@gmail.com>
[base] Tighten the overflow check in `FT_MulFix'.

View File

@ -3807,18 +3807,12 @@ FT_BEGIN_HEADER
/* used to divide a given value by a 16.16 fixed-point factor. */
/* */
/* <Input> */
/* a :: The first multiplier. */
/* b :: The second multiplier. Use a 16.16 factor here whenever */
/* possible (see note below). */
/* a :: The numerator. */
/* b :: The denominator. Use a 16.16 factor here. */
/* */
/* <Return> */
/* The result of `(a*0x10000)/b'. */
/* */
/* <Note> */
/* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */
/* 32~bits, then the division is computed directly. Otherwise, we */
/* use a specialized version of @FT_MulDiv. */
/* */
FT_EXPORT( FT_Long )
FT_DivFix( FT_Long a,
FT_Long b );

View File

@ -397,6 +397,13 @@
/* covers the practical range of use. The actual test below is a bit */
/* tighter to avoid the border case overflows. */
/* */
/* In the case of FT_DivFix, the direct overflow check */
/* */
/* a << 16 <= X - c/2 */
/* */
/* is scaled down by 2^16 and we use */
/* */
/* a <= 65535 - (c >> 17) . */
/* documentation is in freetype.h */
@ -593,7 +600,7 @@
/* check for division by 0 */
q = 0x7FFFFFFFL;
}
else if ( ( a >> 16 ) == 0 )
else if ( a <= 65535L - ( b >> 17 ) )
{
/* compute result directly */
q = (FT_Long)( ( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / b );