From 3c69bd46e27069fac0bfdefdecf5492c17eb01df Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 17 Aug 2009 16:48:13 -0400 Subject: [PATCH] [HB] Avoid int overflow in GPOS Bug 592036 - integer overflow bug causes misrendering of Nepali characters --- src/hb-ot-layout-gpos-private.hh | 20 ++++++++++---------- src/hb-private.h | 3 +++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh index 3aa11601..e665c156 100644 --- a/src/hb-ot-layout-gpos-private.hh +++ b/src/hb-ot-layout-gpos-private.hh @@ -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; diff --git a/src/hb-private.h b/src/hb-private.h index dbeafef1..cdc2b845 100644 --- a/src/hb-private.h +++ b/src/hb-private.h @@ -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 */ -- GitLab