diff options
| author | Paul Eggert | 2011-04-06 20:34:05 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-06 20:34:05 -0700 |
| commit | 5fdb398c4b75b0c834aff7132f90b0ce5317a25a (patch) | |
| tree | 29ebb8fc5700fefdd867fa497eac27fb7d0bcfe0 /src/eval.c | |
| parent | b189fa667ed7ac7b17f9665cd8a0c26316b3c521 (diff) | |
| download | emacs-5fdb398c4b75b0c834aff7132f90b0ce5317a25a.tar.gz emacs-5fdb398c4b75b0c834aff7132f90b0ce5317a25a.zip | |
error: Print 32- and 64-bit integers portably (Bug#8435).
Without this change, on typical 64-bit hosts error ("...%d...", N)
was used to print both 32- and 64-bit integers N, which relied on
undefined behavior.
* lisp.h, src/m/amdx86-64.h, src/m/ia64.h, src/m/ibms390x.h (pEd):
New macro.
* lisp.h (error, verror): Mark as printf-like functions.
* eval.c (verror): Use vsnprintf, not doprnt, to do the real work.
Report overflow in size calculations when allocating printf buffer.
Do not truncate output string at its first null byte.
* xdisp.c (vmessage): Use vsnprintf, not doprnt, to do the real work.
Truncate the output at a character boundary, since vsnprintf does not
do that.
* charset.c (check_iso_charset_parameter): Convert internal
character to string before calling 'error', since %c now has the
printf meaning.
* coding.c (Fdecode_sjis_char, Fdecode_big5_char): Avoid int
overflow when computing char to be passed to 'error'. Do not
pass Lisp_Object to 'error'; pass the integer instead.
* nsfns.m (Fns_do_applescript): Use int, not long, since it's
formatted with plain %d.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/src/eval.c b/src/eval.c index 8b029967e7a..77411a911ee 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1977,21 +1977,26 @@ void | |||
| 1977 | verror (const char *m, va_list ap) | 1977 | verror (const char *m, va_list ap) |
| 1978 | { | 1978 | { |
| 1979 | char buf[200]; | 1979 | char buf[200]; |
| 1980 | EMACS_INT size = 200; | 1980 | size_t size = sizeof buf; |
| 1981 | int mlen; | 1981 | size_t size_max = (size_t) -1; |
| 1982 | char *buffer = buf; | 1982 | char *buffer = buf; |
| 1983 | int allocated = 0; | 1983 | int allocated = 0; |
| 1984 | int used; | ||
| 1984 | Lisp_Object string; | 1985 | Lisp_Object string; |
| 1985 | 1986 | ||
| 1986 | mlen = strlen (m); | ||
| 1987 | |||
| 1988 | while (1) | 1987 | while (1) |
| 1989 | { | 1988 | { |
| 1990 | EMACS_INT used; | 1989 | used = vsnprintf (buffer, size, m, ap); |
| 1991 | used = doprnt (buffer, size, m, m + mlen, ap); | 1990 | if (used < 0) |
| 1991 | used = 0; | ||
| 1992 | if (used < size) | 1992 | if (used < size) |
| 1993 | break; | 1993 | break; |
| 1994 | size *= 2; | 1994 | if (size <= size_max / 2) |
| 1995 | size *= 2; | ||
| 1996 | else if (size < size_max) | ||
| 1997 | size = size_max; | ||
| 1998 | else | ||
| 1999 | memory_full (); | ||
| 1995 | if (allocated) | 2000 | if (allocated) |
| 1996 | buffer = (char *) xrealloc (buffer, size); | 2001 | buffer = (char *) xrealloc (buffer, size); |
| 1997 | else | 2002 | else |
| @@ -2001,7 +2006,7 @@ verror (const char *m, va_list ap) | |||
| 2001 | } | 2006 | } |
| 2002 | } | 2007 | } |
| 2003 | 2008 | ||
| 2004 | string = build_string (buffer); | 2009 | string = make_string (buffer, used); |
| 2005 | if (allocated) | 2010 | if (allocated) |
| 2006 | xfree (buffer); | 2011 | xfree (buffer); |
| 2007 | 2012 | ||