From 5637687fead7d57f73ea9a7677d25b93fb785dc7 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 18 Jul 2011 17:42:24 -0700 Subject: [PATCH] Don't assume that stated character widths fit in int. * character.c (Fchar_width, c_string_width, lisp_string_width): * character.h (CHAR_WIDTH): * indent.c (MULTIBYTE_BYTES_WIDTH): Use sanitize_char_width to avoid undefined and/or bad behavior with outlandish widths. * character.h (sanitize_tab_width): Renamed from sanitize_width, now that we have two such functions. All uses changed. (sanitize_char_width): New inline function. --- src/ChangeLog | 12 ++++++++++++ src/character.c | 6 +++--- src/character.h | 16 ++++++++++++---- src/indent.c | 2 +- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 909bb052fe..54ce0c8df4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2011-07-19 Paul Eggert + + Don't assume that stated character widths fit in int. + * character.c (Fchar_width, c_string_width, lisp_string_width): + * character.h (CHAR_WIDTH): + * indent.c (MULTIBYTE_BYTES_WIDTH): + Use sanitize_char_width to avoid undefined and/or bad behavior + with outlandish widths. + * character.h (sanitize_tab_width): Renamed from sanitize_width, + now that we have two such functions. All uses changed. + (sanitize_char_width): New inline function. + 2011-07-18 Paul Eggert Don't assume that tab-width fits in int. diff --git a/src/character.c b/src/character.c index 8e9b3e3775..c2f23e0d8e 100644 --- a/src/character.c +++ b/src/character.c @@ -326,7 +326,7 @@ usage: (char-width CHAR) */) disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil; if (VECTORP (disp)) - width = ASIZE (disp); + width = sanitize_char_width (ASIZE (disp)); else width = CHAR_WIDTH (c); @@ -358,7 +358,7 @@ c_string_width (const unsigned char *str, EMACS_INT len, int precision, { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = ASIZE (val); + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } @@ -451,7 +451,7 @@ lisp_string_width (Lisp_Object string, EMACS_INT precision, { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = ASIZE (val); + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } diff --git a/src/character.h b/src/character.h index 0c207113c1..09bcf17ab9 100644 --- a/src/character.h +++ b/src/character.h @@ -558,10 +558,10 @@ along with GNU Emacs. If not, see . */ /* Return a non-outlandish value for the tab width. */ -#define SANE_TAB_WIDTH(buf) sanitize_width (XFASTINT (BVAR (buf, tab_width))) - +#define SANE_TAB_WIDTH(buf) \ + sanitize_tab_width (XFASTINT (BVAR (buf, tab_width))) static inline int -sanitize_width (EMACS_INT width) +sanitize_tab_width (EMACS_INT width) { return 0 < width && width <= 1000 ? width : 8; } @@ -579,6 +579,14 @@ sanitize_width (EMACS_INT width) ? 1 \ : ((NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2)))) +/* Return a non-outlandish value for a character width. */ + +static inline int +sanitize_char_width (EMACS_INT width) +{ + return 0 <= width && width <= 1000 ? width : 1000; +} + /* Return the width of character C. The width is measured by how many columns C will occupy on the screen when displayed in the current buffer. */ @@ -586,7 +594,7 @@ sanitize_width (EMACS_INT width) #define CHAR_WIDTH(c) \ (ASCII_CHAR_P (c) \ ? ASCII_CHAR_WIDTH (c) \ - : XINT (CHAR_TABLE_REF (Vchar_width_table, c))) + : sanitize_char_width (XINT (CHAR_TABLE_REF (Vchar_width_table, c)))) /* If C is a variation selector, return the index numnber of the variation selector (1..256). Otherwise, return 0. */ diff --git a/src/indent.c b/src/indent.c index d89c7a9de0..8a2117751a 100644 --- a/src/indent.c +++ b/src/indent.c @@ -284,7 +284,7 @@ skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Ob else \ { \ if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \ - width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \ + width = sanitize_char_width (ASIZE (DISP_CHAR_VECTOR (dp, ch))); \ else \ width = CHAR_WIDTH (ch); \ } \ -- 2.20.1