From d86d0d747f5d23db6cecfbf9385c4db1fb3c6545 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 28 Jul 2011 13:35:09 -0700 Subject: [PATCH] * composite.c: Integer overflow fixes. (get_composition_id): Check for overflow in glyph length calculations. --- src/ChangeLog | 3 +++ src/composite.c | 34 +++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d86ae360275..78b3b97b2d7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,8 @@ 2011-07-28 Paul Eggert + * composite.c: Integer overflow fixes. + (get_composition_id): Check for overflow in glyph length calculations. + * coding.c: Integer and memory overflow fixes. (produce_chars): Redo buffer-overflow calculations to avoid unnecessary integer overflow. Check for size overflow. diff --git a/src/composite.c b/src/composite.c index b25699b9ff4..4ae1d6ebb68 100644 --- a/src/composite.c +++ b/src/composite.c @@ -177,14 +177,24 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, Lisp_Object prop, Lisp_Object string) { Lisp_Object id, length, components, key, *key_contents; - int glyph_len; + ptrdiff_t glyph_len; struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); ptrdiff_t hash_index; EMACS_UINT hash_code; + enum composition_method method; struct composition *cmp; EMACS_INT i; int ch; + /* Maximum length of a string of glyphs. XftGlyphExtents limits this + to INT_MAX, and Emacs may limit it further. */ + enum { + glyph_len_max = + min (INT_MAX, + (min (PTRDIFF_MAX, SIZE_MAX) + / max (MAX_MULTIBYTE_LENGTH, 2 * sizeof (short)))) + }; + /* PROP should be Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) or @@ -320,18 +330,24 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, /* Register the composition in composition_hash_table. */ hash_index = hash_put (hash_table, key, id, hash_code); + method = (NILP (components) + ? COMPOSITION_RELATIVE + : ((INTEGERP (components) || STRINGP (components)) + ? COMPOSITION_WITH_ALTCHARS + : COMPOSITION_WITH_RULE_ALTCHARS)); + + glyph_len = (method == COMPOSITION_WITH_RULE_ALTCHARS + ? (ASIZE (key) + 1) / 2 + : ASIZE (key)); + + if (glyph_len_max < glyph_len) + memory_full (SIZE_MAX); + /* Register the composition in composition_table. */ cmp = (struct composition *) xmalloc (sizeof (struct composition)); - cmp->method = (NILP (components) - ? COMPOSITION_RELATIVE - : ((INTEGERP (components) || STRINGP (components)) - ? COMPOSITION_WITH_ALTCHARS - : COMPOSITION_WITH_RULE_ALTCHARS)); + cmp->method = method; cmp->hash_index = hash_index; - glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS - ? (ASIZE (key) + 1) / 2 - : ASIZE (key)); cmp->glyph_len = glyph_len; cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2); cmp->font = NULL; -- 2.39.2