ref: 336735d8de0bc5f9ef8018ae11d322cb6e59fa4a
parent: 3212852ccea98e0e8eb7188e8b5cb07f26f64fce
author: Alexei Podtelezhnikov <[email protected]>
date: Wed Sep 3 18:55:26 EDT 2014
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2014-09-03 Alexei Podtelezhnikov <[email protected]>
+ [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 <[email protected]>
+
[base] Tighten the overflow check in `FT_MulFix'.
* src/base/ftcalc.c (FT_MulFix) [!FT_LONG64]: Updated.
--- a/include/freetype.h
+++ b/include/freetype.h
@@ -3807,17 +3807,11 @@
/* 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,
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -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 );