Mercurial > hg > octave-lyh > gnulib-hg
changeset 14418:07a5551df5ac
wcswidth, mbswidth: Avoid integer overflow.
* lib/wcswidth.c: Include <limits.h>.
* lib/wcswidth-impl.h (wcswidth): Avoid 'int' overflow.
* lib/mbswidth.c: Include <limits.h>.
(mbsnwidth): Avoid 'int' overflow.
Reported by Jim Meyering.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sat, 12 Mar 2011 13:54:43 +0100 |
parents | c4c3d3ee58b1 |
children | 236edbfecf1d |
files | ChangeLog lib/mbswidth.c lib/wcswidth-impl.h lib/wcswidth.c |
diffstat | 4 files changed, 50 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-03-12 Bruno Haible <bruno@clisp.org> + + wcswidth, mbswidth: Avoid integer overflow. + * lib/wcswidth.c: Include <limits.h>. + * lib/wcswidth-impl.h (wcswidth): Avoid 'int' overflow. + * lib/mbswidth.c: Include <limits.h>. + (mbsnwidth): Avoid 'int' overflow. + Reported by Jim Meyering. + 2011-03-12 Bruno Haible <bruno@clisp.org> futimens, utimensat: Avoid endless recursion on Solaris 10.
--- a/lib/mbswidth.c +++ b/lib/mbswidth.c @@ -35,12 +35,14 @@ /* Get iswcntrl(). */ #include <wctype.h> +/* Get INT_MAX. */ +#include <limits.h> + /* Returns the number of columns needed to represent the multibyte character string pointed to by STRING. If a non-printable character occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. With flags = MBSW_REJECT_INVALID | MBSW_REJECT_UNPRINTABLE, this is - the multibyte analogue of the wcswidth function. - If STRING is not of length < INT_MAX / 2, integer overflow can occur. */ + the multibyte analogue of the wcswidth function. */ int mbswidth (const char *string, int flags) { @@ -50,8 +52,7 @@ /* Returns the number of columns needed to represent the multibyte character string pointed to by STRING of length NBYTES. If a non-printable character occurs, and MBSW_REJECT_UNPRINTABLE is - specified, -1 is returned. - If NBYTES is not < INT_MAX / 2, integer overflow can occur. */ + specified, -1 is returned. */ int mbsnwidth (const char *string, size_t nbytes, int flags) { @@ -135,11 +136,22 @@ w = wcwidth (wc); if (w >= 0) /* A printable multibyte character. */ - width += w; + { + if (w > INT_MAX - width) + goto overflow; + width += w; + } else /* An unprintable multibyte character. */ if (!(flags & MBSW_REJECT_UNPRINTABLE)) - width += (iswcntrl (wc) ? 0 : 1); + { + if (!iswcntrl (wc)) + { + if (width == INT_MAX) + goto overflow; + width++; + } + } else return -1; @@ -157,11 +169,25 @@ unsigned char c = (unsigned char) *p++; if (isprint (c)) - width++; + { + if (width == INT_MAX) + goto overflow; + width++; + } else if (!(flags & MBSW_REJECT_UNPRINTABLE)) - width += (iscntrl (c) ? 0 : 1); + { + if (!iscntrl (c)) + { + if (width == INT_MAX) + goto overflow; + width++; + } + } else return -1; } return width; + + overflow: + return INT_MAX; }