1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-07 20:30:32 -08:00

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'.
This commit is contained in:
Eli Zaretskii 2011-04-23 13:33:28 +03:00
parent 4ffd0d6b56
commit e6c3da2065
13 changed files with 165 additions and 83 deletions

View file

@ -1416,7 +1416,8 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
|| (CONSP (tem)
&& (SYMBOLP (XCAR (tem))
|| CONSP (XCAR (tem))))))
error ("Invalid condition handler");
error ("Invalid condition handler: %s",
SDATA (Fprin1_to_string (tem, Qt)));
}
c.tag = Qnil;
@ -1995,31 +1996,31 @@ verror (const char *m, va_list ap)
size_t size = sizeof buf;
size_t size_max =
min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1;
size_t mlen = strlen (m);
char *buffer = buf;
int used;
size_t used;
Lisp_Object string;
while (1)
{
used = vsnprintf (buffer, size, m, ap);
used = doprnt (buffer, size, m, m + mlen, ap);
if (used < 0)
{
/* Non-C99 vsnprintf, such as w32, returns -1 when SIZE is too small.
Guess a larger USED to work around the incompatibility. */
used = (size <= size_max / 2 ? 2 * size
: size < size_max ? size_max - 1
: size_max);
}
else if (used < size)
/* Note: the -1 below is because `doprnt' returns the number of bytes
excluding the terminating null byte, and it always terminates with a
null byte, even when producing a truncated message. */
if (used < size - 1)
break;
if (size_max <= used)
memory_full ();
size = used + 1;
if (size <= size_max / 2)
size *= 2;
else if (size < size_max - 1)
size = size_max - 1;
else
break; /* and leave the message truncated */
if (buffer != buf)
xfree (buffer);
buffer = (char *) xmalloc (size);
if (buffer == buf)
buffer = (char *) xmalloc (size);
else
buffer = (char *) xrealloc (buffer, size);
}
string = make_string (buffer, used);