[base, cff, truetype] Integer overflows. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2060 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2062 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2063 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2068 * src/base/ftobjs.c (ft_glyphslot_grid_fit_metrics): Use OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG. * src/cff/cf2blues.c (cf2_blues_capture), src/cff/cf2hints.c (cf2_hintmap_adjustHints): Use OVERFLOW_SUB_INT32. * src/truetype/ttgload.c (compute_glyph_metrics): User OVERFLOW_SUB_LONG. * src/truetype/ttinterp.c (Direct_Move, Direct_Move_Orig, Direct_Move_X, Direct_Move_Y, Direct_Move_Orig_X, Direct_Move_Orig_Y, Move_Zp2_Point, Ins_MSIRP): Use OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
diff --git a/ChangeLog b/ChangeLog
index f36748c..e3a42c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
2017-06-03 Werner Lemberg <wl@gnu.org>
+ [base, cff, truetype] Integer overflows.
+
+ Reported as
+
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2060
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2062
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2063
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2068
+
+ * src/base/ftobjs.c (ft_glyphslot_grid_fit_metrics): Use
+ OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG.
+
+ * src/cff/cf2blues.c (cf2_blues_capture), src/cff/cf2hints.c
+ (cf2_hintmap_adjustHints): Use OVERFLOW_SUB_INT32.
+
+ * src/truetype/ttgload.c (compute_glyph_metrics): User
+ OVERFLOW_SUB_LONG.
+
+ * src/truetype/ttinterp.c (Direct_Move, Direct_Move_Orig,
+ Direct_Move_X, Direct_Move_Y, Direct_Move_Orig_X,
+ Direct_Move_Orig_Y, Move_Zp2_Point, Ins_MSIRP): Use
+ OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG.
+
+2017-06-03 Werner Lemberg <wl@gnu.org>
+
* builds/unix/freetype-config.in: Fix pkg-config test (#51162).
Patch directly taken from bug report.
@@ -2855,7 +2880,7 @@
[cff] Implement CFF2 support (2/2).
The font variation code. All parts dependent on the GX code in the
- `truetype' module are guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
+ `truetype' module are guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
In other words, you can still compile the `cff' module without
defining TT_CONFIG_OPTION_GX_VAR_SUPPORT (which brings you CFF2
support without font variation).
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 75e4988..cd5874c 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -581,28 +581,36 @@
metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
- right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );
- bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );
+ right = FT_PIX_CEIL( OVERFLOW_ADD_LONG( metrics->vertBearingX,
+ metrics->width ) );
+ bottom = FT_PIX_CEIL( OVERFLOW_ADD_LONG( metrics->vertBearingY,
+ metrics->height ) );
metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
- metrics->width = right - metrics->vertBearingX;
- metrics->height = bottom - metrics->vertBearingY;
+ metrics->width = OVERFLOW_SUB_LONG( right,
+ metrics->vertBearingX );
+ metrics->height = OVERFLOW_SUB_LONG( bottom,
+ metrics->vertBearingY );
}
else
{
metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
- right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );
- bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );
+ right = FT_PIX_CEIL ( OVERFLOW_ADD_LONG( metrics->horiBearingX,
+ metrics->width ) );
+ bottom = FT_PIX_FLOOR( OVERFLOW_SUB_LONG( metrics->horiBearingY,
+ metrics->height ) );
metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
- metrics->width = right - metrics->horiBearingX;
- metrics->height = metrics->horiBearingY - bottom;
+ metrics->width = OVERFLOW_SUB_LONG( right,
+ metrics->horiBearingX );
+ metrics->height = OVERFLOW_SUB_LONG( metrics->horiBearingY,
+ bottom );
}
metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
diff --git a/src/cff/cf2blues.c b/src/cff/cf2blues.c
index 950c714..a94254d 100644
--- a/src/cff/cf2blues.c
+++ b/src/cff/cf2blues.c
@@ -502,7 +502,8 @@
if ( blues->suppressOvershoot )
dsNew = blues->zone[i].dsFlatEdge;
- else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >=
+ else if ( OVERFLOW_SUB_INT32( blues->zone[i].csTopEdge,
+ bottomHintEdge->csCoord ) >=
blues->blueShift )
{
/* guarantee minimum of 1 pixel overshoot */
diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c
index 89af2ff..d7938c9 100644
--- a/src/cff/cf2hints.c
+++ b/src/cff/cf2hints.c
@@ -512,8 +512,10 @@
if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord )
hintmap->edge[i - 1].scale =
FT_DivFix(
- hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord,
- hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord );
+ OVERFLOW_SUB_INT32( hintmap->edge[i].dsCoord,
+ hintmap->edge[i - 1].dsCoord ),
+ OVERFLOW_SUB_INT32( hintmap->edge[i].csCoord,
+ hintmap->edge[i - 1].csCoord ) );
}
if ( isPair )
@@ -521,8 +523,10 @@
if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord )
hintmap->edge[j - 1].scale =
FT_DivFix(
- hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord,
- hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord );
+ OVERFLOW_SUB_INT32( hintmap->edge[j].dsCoord,
+ hintmap->edge[j - 1].dsCoord ),
+ OVERFLOW_SUB_INT32( hintmap->edge[j].csCoord,
+ hintmap->edge[j - 1].csCoord ) );
i += 1; /* skip upper edge on next loop */
}
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index e5a3da3..66e8228 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2100,8 +2100,8 @@
}
/* set glyph dimensions */
- glyph->metrics.width = bbox.xMax - bbox.xMin;
- glyph->metrics.height = bbox.yMax - bbox.yMin;
+ glyph->metrics.width = OVERFLOW_SUB_LONG( bbox.xMax, bbox.xMin );
+ glyph->metrics.height = OVERFLOW_SUB_LONG( bbox.yMax, bbox.yMin );
/* Now take care of vertical metrics. In the case where there is */
/* no vertical information within the font (relatively common), */
@@ -2137,7 +2137,8 @@
/* table in the font. Otherwise, we use the */
/* values defined in the horizontal header. */
- height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin,
+ height = (FT_Short)FT_DivFix( OVERFLOW_SUB_LONG( bbox.yMax,
+ bbox.yMin ),
y_scale );
if ( face->os2.version != 0xFFFFU )
advance = (FT_Pos)( face->os2.sTypoAscender -
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index cbb7540..85e9e08 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -1676,7 +1676,9 @@
if ( SUBPIXEL_HINTING_INFINALITY &&
( !exc->ignore_x_mode ||
( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
- zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+ zone->cur[point].x = OVERFLOW_ADD_LONG(
+ zone->cur[point].x,
+ FT_MulDiv( distance, v, exc->F_dot_P ) );
else
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
@@ -1685,12 +1687,16 @@
/* diagonal moves, but only post-IUP. DejaVu tries to adjust */
/* diagonal stems like on `Z' and `z' post-IUP. */
if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility )
- zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+ zone->cur[point].x = OVERFLOW_ADD_LONG(
+ zone->cur[point].x,
+ FT_MulDiv( distance, v, exc->F_dot_P ) );
else
#endif
if ( NO_SUBPIXEL_HINTING )
- zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+ zone->cur[point].x = OVERFLOW_ADD_LONG(
+ zone->cur[point].x,
+ FT_MulDiv( distance, v, exc->F_dot_P ) );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
@@ -1705,7 +1711,9 @@
exc->iupx_called &&
exc->iupy_called ) )
#endif
- zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
+ zone->cur[point].y = OVERFLOW_ADD_LONG(
+ zone->cur[point].y,
+ FT_MulDiv( distance, v, exc->F_dot_P ) );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1741,12 +1749,16 @@
v = exc->GS.freeVector.x;
if ( v != 0 )
- zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+ zone->org[point].x = OVERFLOW_ADD_LONG(
+ zone->org[point].x,
+ FT_MulDiv( distance, v, exc->F_dot_P ) );
v = exc->GS.freeVector.y;
if ( v != 0 )
- zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
+ zone->org[point].y = OVERFLOW_ADD_LONG(
+ zone->org[point].y,
+ FT_MulDiv( distance, v, exc->F_dot_P ) );
}
@@ -1769,18 +1781,18 @@
{
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode )
- zone->cur[point].x += distance;
+ zone->cur[point].x = OVERFLOW_ADD_LONG( zone->cur[point].x, distance );
else
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility )
- zone->cur[point].x += distance;
+ zone->cur[point].x = OVERFLOW_ADD_LONG( zone->cur[point].x, distance );
else
#endif
if ( NO_SUBPIXEL_HINTING )
- zone->cur[point].x += distance;
+ zone->cur[point].x = OVERFLOW_ADD_LONG( zone->cur[point].x, distance );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
@@ -1799,7 +1811,7 @@
exc->backward_compatibility &&
exc->iupx_called && exc->iupy_called ) )
#endif
- zone->cur[point].y += distance;
+ zone->cur[point].y = OVERFLOW_ADD_LONG( zone->cur[point].y, distance );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1823,7 +1835,7 @@
{
FT_UNUSED( exc );
- zone->org[point].x += distance;
+ zone->org[point].x = OVERFLOW_ADD_LONG( zone->org[point].x, distance );
}
@@ -1835,7 +1847,7 @@
{
FT_UNUSED( exc );
- zone->org[point].y += distance;
+ zone->org[point].y = OVERFLOW_ADD_LONG( zone->org[point].y, distance );
}
@@ -5392,7 +5404,8 @@
if ( !( SUBPIXEL_HINTING_MINIMAL &&
exc->backward_compatibility ) )
#endif
- exc->zp2.cur[point].x += dx;
+ exc->zp2.cur[point].x = OVERFLOW_ADD_LONG( exc->zp2.cur[point].x,
+ dx );
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
@@ -5406,7 +5419,8 @@
exc->iupx_called &&
exc->iupy_called ) )
#endif
- exc->zp2.cur[point].y += dy;
+ exc->zp2.cur[point].y = OVERFLOW_ADD_LONG( exc->zp2.cur[point].y,
+ dy );
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
@@ -5781,14 +5795,18 @@
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* subpixel hinting - make MSIRP respect CVT cut-in; */
- if ( SUBPIXEL_HINTING_INFINALITY &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 &&
- FT_ABS( distance - args[1] ) >= control_value_cutin )
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 &&
+ FT_ABS( OVERFLOW_SUB_LONG( distance,
+ args[1] ) ) >= control_value_cutin )
distance = args[1];
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
- exc->func_move( exc, &exc->zp1, point, args[1] - distance );
+ exc->func_move( exc,
+ &exc->zp1,
+ point,
+ OVERFLOW_SUB_LONG( args[1], distance ) );
exc->GS.rp1 = exc->GS.rp0;
exc->GS.rp2 = point;