From: Paul Eggert Date: Mon, 16 May 2011 05:08:59 +0000 (-0700) Subject: * character.c (lisp_string_width): Check for string overflow. X-Git-Tag: emacs-pretest-24.0.90~104^2~618^2~239^2~19 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2b4560a850d2ea0767d0a3c4db19e4468f61b4eb;p=emacs.git * character.c (lisp_string_width): Check for string overflow. Use EMACS_INT, not int, for string indexes and lengths; in particular, 2nd arg is now EMACS_INT, not int. Do not crash if the resulting string length overflows an EMACS_INT; instead, report a string overflow if no precision given. When checking for precision exhaustion, use a check that cannot possibly have integer overflow. (Bug#8675) * character.h (lisp_string_width): Adjust to new signature. --- diff --git a/src/ChangeLog b/src/ChangeLog index 178ebf78932..944a5dfbecb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,14 @@ 2011-05-16 Paul Eggert + * character.c (lisp_string_width): Check for string overflow. + Use EMACS_INT, not int, for string indexes and lengths; in + particular, 2nd arg is now EMACS_INT, not int. Do not crash if + the resulting string length overflows an EMACS_INT; instead, + report a string overflow if no precision given. When checking for + precision exhaustion, use a check that cannot possibly have + integer overflow. (Bug#8675) + * character.h (lisp_string_width): Adjust to new signature. + * alloc.c (string_overflow): New function. (Fmake_string): Use it. This doesn't change behavior, but saves a few bytes and will simplify future changes. diff --git a/src/character.c b/src/character.c index 6a8b86d5d87..a03c081a716 100644 --- a/src/character.c +++ b/src/character.c @@ -35,6 +35,7 @@ along with GNU Emacs. If not, see . */ #include #include +#include #include "lisp.h" #include "character.h" #include "buffer.h" @@ -404,7 +405,7 @@ strwidth (const char *str, EMACS_INT len) in *NCHARS and *NBYTES respectively. */ EMACS_INT -lisp_string_width (Lisp_Object string, int precision, +lisp_string_width (Lisp_Object string, EMACS_INT precision, EMACS_INT *nchars, EMACS_INT *nbytes) { EMACS_INT len = SCHARS (string); @@ -419,7 +420,7 @@ lisp_string_width (Lisp_Object string, int precision, while (i < len) { - int chars, bytes, thiswidth; + EMACS_INT chars, bytes, thiswidth; Lisp_Object val; int cmp_id; EMACS_INT ignore, end; @@ -437,7 +438,11 @@ lisp_string_width (Lisp_Object string, int precision, int c; if (multibyte) - c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); + { + int cbytes; + c = STRING_CHAR_AND_LENGTH (str + i_byte, cbytes); + bytes = cbytes; + } else c = str[i_byte], bytes = 1; chars = 1; @@ -455,8 +460,14 @@ lisp_string_width (Lisp_Object string, int precision, } } - if (precision > 0 - && (width + thiswidth > precision)) + if (precision <= 0) + { +#ifdef emacs + if (INT_ADD_OVERFLOW (width, thiswidth)) + string_overflow (); +#endif + } + else if (precision - width < thiswidth) { *nchars = i; *nbytes = i_byte; diff --git a/src/character.h b/src/character.h index 864882db7f6..5877d145d9e 100644 --- a/src/character.h +++ b/src/character.h @@ -612,7 +612,7 @@ extern EMACS_INT str_to_unibyte (const unsigned char *, unsigned char *, extern EMACS_INT strwidth (const char *, EMACS_INT); extern EMACS_INT c_string_width (const unsigned char *, EMACS_INT, int, EMACS_INT *, EMACS_INT *); -extern EMACS_INT lisp_string_width (Lisp_Object, int, +extern EMACS_INT lisp_string_width (Lisp_Object, EMACS_INT, EMACS_INT *, EMACS_INT *); extern Lisp_Object Qcharacterp;