aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorEli Zaretskii2011-04-23 13:33:28 +0300
committerEli Zaretskii2011-04-23 13:33:28 +0300
commite6c3da2065ac72cc4e1a2bef22d367cd75401892 (patch)
tree1f6fcbee1e12f63096d2221a89f5436b831862a9 /src/eval.c
parent4ffd0d6b569d252e4e807d4e9c9d6a5bd5b08640 (diff)
downloademacs-e6c3da2065ac72cc4e1a2bef22d367cd75401892.tar.gz
emacs-e6c3da2065ac72cc4e1a2bef22d367cd75401892.zip
Fix doprnt so it could be used safely in `verror'. (Bug#8435)
src/doprnt.c: Include limits.h. (SIZE_MAX): New macro. (doprnt): Return a size_t value. 2nd arg is now size_t. Many local variables are now size_t instead of int or unsigned. Improve overflow protection. Support `l' modifier for integer conversions. Support %l conversion. Don't assume an EMACS_INT argument for integer conversions and for %c. src/lisp.h (doprnt): Restore prototype. src/makefile.w32-in ($(BLD)/callint.$(O)): Depend on $(SRC)/character.h. src/Makefile.in (base_obj): Add back doprnt.o. src/deps.mk (doprnt.o): Add back prerequisites. (callint.o): Depend on character.h. src/eval.c (internal_lisp_condition_case): Include the handler representation in the error message. (verror): Call doprnt instead of vsnprintf. Fix an off-by-one bug when breaking from the loop. src/xdisp.c (vmessage): Call doprnt instead of vsnprintf. src/callint.c (Fcall_interactively): When displaying error message about invalid control letter, pass the character's codepoint, not a pointer to its multibyte form. Improve display of the character in octal and display also its hex code. src/character.c (char_string): Use %x to display the (unsigned) codepoint of an invalid character, to avoid displaying a bogus negative value. src/font.c (check_otf_features): Pass SDATA of SYMBOL_NAME to `error', not SYMBOL_NAME itself. src/coding.c (Fencode_sjis_char, Fencode_big5_char): Use %c for character arguments to `error'. src/charset.c (check_iso_charset_parameter): Fix incorrect argument to `error' in error message about FINAL_CHAR argument. Make sure FINAL_CHAR is a character, and use %c when it is passed as argument to `error'.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/src/eval.c b/src/eval.c
index b843ca5b2ec..c3676720940 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1416,7 +1416,8 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1416 || (CONSP (tem) 1416 || (CONSP (tem)
1417 && (SYMBOLP (XCAR (tem)) 1417 && (SYMBOLP (XCAR (tem))
1418 || CONSP (XCAR (tem)))))) 1418 || CONSP (XCAR (tem))))))
1419 error ("Invalid condition handler"); 1419 error ("Invalid condition handler: %s",
1420 SDATA (Fprin1_to_string (tem, Qt)));
1420 } 1421 }
1421 1422
1422 c.tag = Qnil; 1423 c.tag = Qnil;
@@ -1995,31 +1996,31 @@ verror (const char *m, va_list ap)
1995 size_t size = sizeof buf; 1996 size_t size = sizeof buf;
1996 size_t size_max = 1997 size_t size_max =
1997 min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1; 1998 min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1;
1999 size_t mlen = strlen (m);
1998 char *buffer = buf; 2000 char *buffer = buf;
1999 int used; 2001 size_t used;
2000 Lisp_Object string; 2002 Lisp_Object string;
2001 2003
2002 while (1) 2004 while (1)
2003 { 2005 {
2004 used = vsnprintf (buffer, size, m, ap); 2006 used = doprnt (buffer, size, m, m + mlen, ap);
2005 2007
2006 if (used < 0) 2008 /* Note: the -1 below is because `doprnt' returns the number of bytes
2007 { 2009 excluding the terminating null byte, and it always terminates with a
2008 /* Non-C99 vsnprintf, such as w32, returns -1 when SIZE is too small. 2010 null byte, even when producing a truncated message. */
2009 Guess a larger USED to work around the incompatibility. */ 2011 if (used < size - 1)
2010 used = (size <= size_max / 2 ? 2 * size
2011 : size < size_max ? size_max - 1
2012 : size_max);
2013 }
2014 else if (used < size)
2015 break; 2012 break;
2016 if (size_max <= used) 2013 if (size <= size_max / 2)
2017 memory_full (); 2014 size *= 2;
2018 size = used + 1; 2015 else if (size < size_max - 1)
2016 size = size_max - 1;
2017 else
2018 break; /* and leave the message truncated */
2019 2019
2020 if (buffer != buf) 2020 if (buffer == buf)
2021 xfree (buffer); 2021 buffer = (char *) xmalloc (size);
2022 buffer = (char *) xmalloc (size); 2022 else
2023 buffer = (char *) xrealloc (buffer, size);
2023 } 2024 }
2024 2025
2025 string = make_string (buffer, used); 2026 string = make_string (buffer, used);