From df0b2940c2ac0172d3548829913534d303f9ea45 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 3 Feb 2012 11:24:22 -0800 Subject: [PATCH] Handle overflow when computing char display width (Bug#9496). * character.c (char_width): Return EMACS_INT, not int. (char_width, c_string_width): Check for overflow when computing the width; this is possible now that individual characters can have unbounded width. Problem introduced by merge from Emacs 23 on 2012-01-19. --- src/ChangeLog | 9 +++++++++ src/character.c | 24 +++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 2667f4ce4f..d6decb7b40 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-02-03 Paul Eggert + + Handle overflow when computing char display width (Bug#9496). + * character.c (char_width): Return EMACS_INT, not int. + (char_width, c_string_width): Check for overflow when + computing the width; this is possible now that individual + characters can have unbounded width. Problem introduced + by merge from Emacs 23 on 2012-01-19. + 2012-02-02 Michael Albinus * dbusbind.c (Fdbus_register_method): Mention the return value diff --git a/src/character.c b/src/character.c index 593fbcece0..82bc2bfef4 100644 --- a/src/character.c +++ b/src/character.c @@ -311,10 +311,10 @@ If the multibyte character does not represent a byte, return -1. */) /* Return width (columns) of C considering the buffer display table DP. */ -static int +static EMACS_INT char_width (int c, struct Lisp_Char_Table *dp) { - int width = CHAR_WIDTH (c); + EMACS_INT width = CHAR_WIDTH (c); if (dp) { @@ -326,7 +326,12 @@ char_width (int c, struct Lisp_Char_Table *dp) { ch = AREF (disp, i); if (CHARACTERP (ch)) - width += CHAR_WIDTH (XFASTINT (ch)); + { + int w = CHAR_WIDTH (XFASTINT (ch)); + if (INT_ADD_OVERFLOW (width, w)) + string_overflow (); + width += w; + } } } return width; @@ -340,7 +345,8 @@ Tab is taken to occupy `tab-width' columns. usage: (char-width CHAR) */) (Lisp_Object ch) { - int c, width; + int c; + EMACS_INT width; CHECK_CHARACTER (ch); c = XINT (ch); @@ -367,10 +373,14 @@ c_string_width (const unsigned char *str, EMACS_INT len, int precision, { int bytes; int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); - int thiswidth = char_width (c, dp); + EMACS_INT thiswidth = char_width (c, dp); - if (precision > 0 - && (width + thiswidth > precision)) + if (precision <= 0) + { + if (INT_ADD_OVERFLOW (width, thiswidth)) + string_overflow (); + } + else if (precision - width < thiswidth) { *nchars = i; *nbytes = i_byte; -- 2.20.1