[HB] Avoid int overflow in GPOS
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 17 Aug 2009 20:48:13 +0000 (16:48 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 2 Nov 2009 19:40:44 +0000 (14:40 -0500)
Bug 592036 - integer overflow bug causes misrendering of Nepali characters

src/hb-ot-layout-gpos-private.hh
src/hb-private.h

index 3aa1160..e665c15 100644 (file)
@@ -102,13 +102,13 @@ struct ValueRecord {
     y_scale = context->font->y_scale;
     /* design units -> fractional pixel */
     if (format & xPlacement)
-      glyph_pos->x_pos += x_scale * *(SHORT*)values++ / 0x10000;
+      glyph_pos->x_pos += _hb_16dot16_mul_trunc (x_scale, *(SHORT*)values++);
     if (format & yPlacement)
-      glyph_pos->y_pos += y_scale * *(SHORT*)values++ / 0x10000;
+      glyph_pos->y_pos += _hb_16dot16_mul_trunc (y_scale, *(SHORT*)values++);
     if (format & xAdvance)
-      glyph_pos->x_advance += x_scale * *(SHORT*)values++ / 0x10000;
+      glyph_pos->x_advance += _hb_16dot16_mul_trunc (x_scale, *(SHORT*)values++);
     if (format & yAdvance)
-      glyph_pos->y_advance += y_scale * *(SHORT*)values++ / 0x10000;
+      glyph_pos->y_advance += _hb_16dot16_mul_trunc (y_scale, *(SHORT*)values++);
 
     x_ppem = context->font->x_ppem;
     y_ppem = context->font->y_ppem;
@@ -150,8 +150,8 @@ struct AnchorFormat1
   inline void get_anchor (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id,
                          hb_position_t *x, hb_position_t *y) const
   {
-      *x = context->font->x_scale * xCoordinate / 0x10000;
-      *y = context->font->y_scale * yCoordinate / 0x10000;
+      *x = _hb_16dot16_mul_trunc (context->font->x_scale, xCoordinate);
+      *y = _hb_16dot16_mul_trunc (context->font->y_scale, yCoordinate);
   }
 
   inline bool sanitize (SANITIZE_ARG_DEF) {
@@ -175,8 +175,8 @@ struct AnchorFormat2
                          hb_position_t *x, hb_position_t *y) const
   {
       /* TODO Contour */
-      *x = context->font->x_scale * xCoordinate / 0x10000;
-      *y = context->font->y_scale * yCoordinate / 0x10000;
+      *x = _hb_16dot16_mul_trunc (context->font->x_scale, xCoordinate);
+      *y = _hb_16dot16_mul_trunc (context->font->y_scale, yCoordinate);
   }
 
   inline bool sanitize (SANITIZE_ARG_DEF) {
@@ -200,8 +200,8 @@ struct AnchorFormat3
   inline void get_anchor (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id,
                          hb_position_t *x, hb_position_t *y) const
   {
-      *x = context->font->x_scale * xCoordinate / 0x10000;
-      *y = context->font->y_scale * yCoordinate / 0x10000;
+      *x = _hb_16dot16_mul_trunc (context->font->x_scale, xCoordinate);
+      *y = _hb_16dot16_mul_trunc (context->font->y_scale, yCoordinate);
 
       if (context->font->x_ppem)
        *x += (this+xDeviceTable).get_delta (context->font->x_ppem) << 6;
index dbeafef..cdc2b84 100644 (file)
@@ -201,6 +201,9 @@ _hb_popcount32 (uint32_t mask)
 }
 
 
+/* Multiplies a 16dot16 value by another value, then truncates the result */
+#define _hb_16dot16_mul_trunc(A,B) ((int64_t) (A) * (B) / 0x10000)
+
 #include "hb-object-private.h"
 
 #endif /* HB_PRIVATE_H */