aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-08-29 08:43:34 -0700
committerPaul Eggert2011-08-29 08:43:34 -0700
commit62f19c197d32e8773a284616d575686d87903b7d (patch)
tree237de2d21e8a33f6821248890c01de7d83dbcba4 /src
parent005d87bd2306e943a16b86c36d1482651d9932d8 (diff)
downloademacs-62f19c197d32e8773a284616d575686d87903b7d.tar.gz
emacs-62f19c197d32e8773a284616d575686d87903b7d.zip
sprintf-related integer and memory overflow issues.
* doprnt.c (doprnt): Support printing ptrdiff_t and intmax_t values. (esprintf, esnprintf, exprintf, evxprintf): New functions. * keyboard.c (command_loop_level): Now EMACS_INT, not int. (cmd_error): kbd macro iterations count is now EMACS_INT, not int. (modify_event_symbol): Do not assume that the length of name_alist_or_stem is safe to alloca and fits in int. (Fexecute_extended_command): Likewise for function name and binding. (Frecursion_depth): Wrap around reliably on integer overflow. * keymap.c (push_key_description): First arg is now EMACS_INT, not int, since some callers pass EMACS_INT values. (Fsingle_key_description): Don't crash if symbol name contains more than MAX_ALLOCA bytes. * minibuf.c (minibuf_level): Now EMACS_INT, not int. (get_minibuffer): Arg is now EMACS_INT, not int. * lisp.h (get_minibuffer, push_key_description): Reflect API changes. (esprintf, esnprintf, exprintf, evxprintf): New decls. * window.h (command_loop_level, minibuf_level): Reflect API changes.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog22
-rw-r--r--src/doprnt.c224
-rw-r--r--src/keyboard.c46
-rw-r--r--src/keymap.c19
-rw-r--r--src/lisp.h14
-rw-r--r--src/minibuf.c8
-rw-r--r--src/window.h4
7 files changed, 252 insertions, 85 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index bb2a0d20c1f..d60c57dfd53 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,25 @@
12011-08-29 Paul Eggert <eggert@cs.ucla.edu>
2
3 sprintf-related integer and memory overflow issues.
4
5 * doprnt.c (doprnt): Support printing ptrdiff_t and intmax_t values.
6 (esprintf, esnprintf, exprintf, evxprintf): New functions.
7 * keyboard.c (command_loop_level): Now EMACS_INT, not int.
8 (cmd_error): kbd macro iterations count is now EMACS_INT, not int.
9 (modify_event_symbol): Do not assume that the length of
10 name_alist_or_stem is safe to alloca and fits in int.
11 (Fexecute_extended_command): Likewise for function name and binding.
12 (Frecursion_depth): Wrap around reliably on integer overflow.
13 * keymap.c (push_key_description): First arg is now EMACS_INT, not int,
14 since some callers pass EMACS_INT values.
15 (Fsingle_key_description): Don't crash if symbol name contains more
16 than MAX_ALLOCA bytes.
17 * minibuf.c (minibuf_level): Now EMACS_INT, not int.
18 (get_minibuffer): Arg is now EMACS_INT, not int.
19 * lisp.h (get_minibuffer, push_key_description): Reflect API changes.
20 (esprintf, esnprintf, exprintf, evxprintf): New decls.
21 * window.h (command_loop_level, minibuf_level): Reflect API changes.
22
12011-08-26 Paul Eggert <eggert@cs.ucla.edu> 232011-08-26 Paul Eggert <eggert@cs.ucla.edu>
2 24
3 Integer and memory overflow issues (Bug#9196). 25 Integer and memory overflow issues (Bug#9196).
diff --git a/src/doprnt.c b/src/doprnt.c
index 79f9f36e461..dae1dab04d7 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -70,9 +70,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
70 %<flags><width><precision><length>character 70 %<flags><width><precision><length>character
71 71
72 where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length 72 where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length
73 is empty or l or the value of the pI macro. Also, %% in a format 73 is empty or l or the value of the pD or pI or pMd (sans "d") macros.
74 stands for a single % in the output. A % that does not introduce a 74 Also, %% in a format stands for a single % in the output. A % that
75 valid %-sequence causes undefined behavior. 75 does not introduce a valid %-sequence causes undefined behavior.
76 76
77 The + flag character inserts a + before any positive number, while a space 77 The + flag character inserts a + before any positive number, while a space
78 inserts a space before any positive number; these flags only affect %d, %o, 78 inserts a space before any positive number; these flags only affect %d, %o,
@@ -85,8 +85,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
85 modifier: it is supported for %d, %o, and %x conversions of integral 85 modifier: it is supported for %d, %o, and %x conversions of integral
86 arguments, must immediately precede the conversion specifier, and means that 86 arguments, must immediately precede the conversion specifier, and means that
87 the respective argument is to be treated as `long int' or `unsigned long 87 the respective argument is to be treated as `long int' or `unsigned long
88 int'. Similarly, the value of the pI macro means to use EMACS_INT or 88 int'. Similarly, the value of the pD macro means to use ptrdiff_t,
89 EMACS_UINT and the empty length modifier means `int' or `unsigned int'. 89 the value of the pI macro means to use EMACS_INT or EMACS_UINT, the
90 value of the pMd etc. macros means to use intmax_t or uintmax_t,
91 and the empty length modifier means `int' or `unsigned int'.
90 92
91 The width specifier supplies a lower limit for the length of the printed 93 The width specifier supplies a lower limit for the length of the printed
92 representation. The padding, if any, normally goes on the left, but it goes 94 representation. The padding, if any, normally goes on the left, but it goes
@@ -173,8 +175,17 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
173 { 175 {
174 ptrdiff_t size_bound = 0; 176 ptrdiff_t size_bound = 0;
175 EMACS_INT width; /* Columns occupied by STRING on display. */ 177 EMACS_INT width; /* Columns occupied by STRING on display. */
176 int long_flag = 0; 178 enum {
177 int pIlen = sizeof pI - 1; 179 pDlen = sizeof pD - 1,
180 pIlen = sizeof pI - 1,
181 pMlen = sizeof pMd - 2
182 };
183 enum {
184 no_modifier, long_modifier, pD_modifier, pI_modifier, pM_modifier
185 } length_modifier = no_modifier;
186 static char const modifier_len[] = { 0, 1, pDlen, pIlen, pMlen };
187 int maxmlen = max (max (1, pDlen), max (pIlen, pMlen));
188 int mlen;
178 189
179 fmt++; 190 fmt++;
180 /* Copy this one %-spec into fmtcpy. */ 191 /* Copy this one %-spec into fmtcpy. */
@@ -213,19 +224,26 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
213 fmt++; 224 fmt++;
214 } 225 }
215 226
216 if (0 < pIlen && pIlen <= format_end - fmt 227 /* Check for the length modifiers in textual length order, so
217 && memcmp (fmt, pI, pIlen) == 0) 228 that longer modifiers override shorter ones. */
229 for (mlen = 1; mlen <= maxmlen; mlen++)
218 { 230 {
219 long_flag = 2; 231 if (format_end - fmt < mlen)
220 memcpy (string, fmt + 1, pIlen); 232 break;
221 string += pIlen; 233 if (mlen == 1 && *fmt == 'l')
222 fmt += pIlen; 234 length_modifier = long_modifier;
223 } 235 if (mlen == pDlen && memcmp (fmt, pD, pDlen) == 0)
224 else if (fmt < format_end && *fmt == 'l') 236 length_modifier = pD_modifier;
225 { 237 if (mlen == pIlen && memcmp (fmt, pI, pIlen) == 0)
226 long_flag = 1; 238 length_modifier = pI_modifier;
227 *string++ = *++fmt; 239 if (mlen == pMlen && memcmp (fmt, pMd, pMlen) == 0)
240 length_modifier = pM_modifier;
228 } 241 }
242
243 mlen = modifier_len[length_modifier];
244 memcpy (string, fmt + 1, mlen);
245 string += mlen;
246 fmt += mlen;
229 *string = 0; 247 *string = 0;
230 248
231 /* Make the size bound large enough to handle floating point formats 249 /* Make the size bound large enough to handle floating point formats
@@ -252,55 +270,78 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
252/* case 'b': */ 270/* case 'b': */
253 case 'l': 271 case 'l':
254 case 'd': 272 case 'd':
255 { 273 switch (length_modifier)
256 int i; 274 {
257 long l; 275 case no_modifier:
258
259 if (1 < long_flag)
260 { 276 {
261 EMACS_INT ll = va_arg (ap, EMACS_INT); 277 int v = va_arg (ap, int);
262 sprintf (sprintf_buffer, fmtcpy, ll); 278 sprintf (sprintf_buffer, fmtcpy, v);
263 } 279 }
264 else if (long_flag) 280 break;
281 case long_modifier:
265 { 282 {
266 l = va_arg(ap, long); 283 long v = va_arg (ap, long);
267 sprintf (sprintf_buffer, fmtcpy, l); 284 sprintf (sprintf_buffer, fmtcpy, v);
268 } 285 }
269 else 286 break;
287 case pD_modifier:
288 signed_pD_modifier:
270 { 289 {
271 i = va_arg(ap, int); 290 ptrdiff_t v = va_arg (ap, ptrdiff_t);
272 sprintf (sprintf_buffer, fmtcpy, i); 291 sprintf (sprintf_buffer, fmtcpy, v);
273 } 292 }
274 /* Now copy into final output, truncating as necessary. */ 293 break;
275 string = sprintf_buffer; 294 case pI_modifier:
276 goto doit; 295 {
277 } 296 EMACS_INT v = va_arg (ap, EMACS_INT);
297 sprintf (sprintf_buffer, fmtcpy, v);
298 }
299 break;
300 case pM_modifier:
301 {
302 intmax_t v = va_arg (ap, intmax_t);
303 sprintf (sprintf_buffer, fmtcpy, v);
304 }
305 break;
306 }
307 /* Now copy into final output, truncating as necessary. */
308 string = sprintf_buffer;
309 goto doit;
278 310
279 case 'o': 311 case 'o':
280 case 'x': 312 case 'x':
281 { 313 switch (length_modifier)
282 unsigned u; 314 {
283 unsigned long ul; 315 case no_modifier:
284
285 if (1 < long_flag)
286 { 316 {
287 EMACS_UINT ull = va_arg (ap, EMACS_UINT); 317 unsigned v = va_arg (ap, unsigned);
288 sprintf (sprintf_buffer, fmtcpy, ull); 318 sprintf (sprintf_buffer, fmtcpy, v);
289 } 319 }
290 else if (long_flag) 320 break;
321 case long_modifier:
291 { 322 {
292 ul = va_arg(ap, unsigned long); 323 unsigned long v = va_arg (ap, unsigned long);
293 sprintf (sprintf_buffer, fmtcpy, ul); 324 sprintf (sprintf_buffer, fmtcpy, v);
294 } 325 }
295 else 326 break;
327 case pD_modifier:
328 goto signed_pD_modifier;
329 case pI_modifier:
296 { 330 {
297 u = va_arg(ap, unsigned); 331 EMACS_UINT v = va_arg (ap, EMACS_UINT);
298 sprintf (sprintf_buffer, fmtcpy, u); 332 sprintf (sprintf_buffer, fmtcpy, v);
299 } 333 }
300 /* Now copy into final output, truncating as necessary. */ 334 break;
301 string = sprintf_buffer; 335 case pM_modifier:
302 goto doit; 336 {
303 } 337 uintmax_t v = va_arg (ap, uintmax_t);
338 sprintf (sprintf_buffer, fmtcpy, v);
339 }
340 break;
341 }
342 /* Now copy into final output, truncating as necessary. */
343 string = sprintf_buffer;
344 goto doit;
304 345
305 case 'f': 346 case 'f':
306 case 'e': 347 case 'e':
@@ -426,3 +467,82 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
426 SAFE_FREE (); 467 SAFE_FREE ();
427 return bufptr - buffer; 468 return bufptr - buffer;
428} 469}
470
471/* Format to an unbounded buffer BUF. This is like sprintf, except it
472 is not limited to returning an 'int' so it doesn't have a silly 2
473 GiB limit on typical 64-bit hosts. However, it is limited to the
474 Emacs-style formats that doprnt supports.
475
476 Return the number of bytes put into BUF, excluding the terminating
477 '\0'. */
478ptrdiff_t
479esprintf (char *buf, char const *format, ...)
480{
481 ptrdiff_t nbytes;
482 va_list ap;
483 va_start (ap, format);
484 nbytes = doprnt (buf, TYPE_MAXIMUM (ptrdiff_t), format, 0, ap);
485 va_end (ap);
486 return nbytes;
487}
488
489/* Format to a buffer BUF of positive size BUFSIZE. This is like
490 snprintf, except it is not limited to returning an 'int' so it
491 doesn't have a silly 2 GiB limit on typical 64-bit hosts. However,
492 it is limited to the Emacs-style formats that doprnt supports, and
493 BUFSIZE must be positive.
494
495 Return the number of bytes put into BUF, excluding the terminating
496 '\0'. Unlike snprintf, always return a nonnegative value less than
497 BUFSIZE; if the output is truncated, return BUFSIZE - 1, which is
498 the length of the truncated output. */
499ptrdiff_t
500esnprintf (char *buf, ptrdiff_t bufsize, char const *format, ...)
501{
502 ptrdiff_t nbytes;
503 va_list ap;
504 va_start (ap, format);
505 nbytes = doprnt (buf, bufsize, format, 0, ap);
506 va_end (ap);
507 return nbytes;
508}
509
510/* Format to buffer *BUF of positive size *BUFSIZE, reallocating *BUF
511 and updating *BUFSIZE if the buffer is too small, and otherwise
512 behaving line esprintf. When reallocating, free *BUF unless it is
513 equal to NONHEAPBUF, and if BUFSIZE_MAX is nonnegative then signal
514 memory exhaustion instead of growing the buffer size past
515 BUFSIZE_MAX. */
516ptrdiff_t
517exprintf (char **buf, ptrdiff_t *bufsize,
518 char const *nonheapbuf, ptrdiff_t bufsize_max,
519 char const *format, ...)
520{
521 ptrdiff_t nbytes;
522 va_list ap;
523 va_start (ap, format);
524 nbytes = evxprintf (buf, bufsize, nonheapbuf, bufsize_max, format, ap);
525 va_end (ap);
526 return nbytes;
527}
528
529/* Act like exprintf, except take a va_list. */
530ptrdiff_t
531evxprintf (char **buf, ptrdiff_t *bufsize,
532 char const *nonheapbuf, ptrdiff_t bufsize_max,
533 char const *format, va_list ap)
534{
535 for (;;)
536 {
537 ptrdiff_t nbytes;
538 va_list ap_copy;
539 va_copy (ap_copy, ap);
540 nbytes = doprnt (*buf, *bufsize, format, 0, ap_copy);
541 va_end (ap_copy);
542 if (nbytes < *bufsize - 1)
543 return nbytes;
544 if (*buf != nonheapbuf)
545 xfree (*buf);
546 *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1);
547 }
548}
diff --git a/src/keyboard.c b/src/keyboard.c
index ab93e0ccd24..51eac369e7c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -196,7 +196,7 @@ int immediate_quit;
196int quit_char; 196int quit_char;
197 197
198/* Current depth in recursive edits. */ 198/* Current depth in recursive edits. */
199int command_loop_level; 199EMACS_INT command_loop_level;
200 200
201/* If not Qnil, this is a switch-frame event which we decided to put 201/* If not Qnil, this is a switch-frame event which we decided to put
202 off until the end of a key sequence. This should be read as the 202 off until the end of a key sequence. This should be read as the
@@ -998,7 +998,8 @@ static Lisp_Object
998cmd_error (Lisp_Object data) 998cmd_error (Lisp_Object data)
999{ 999{
1000 Lisp_Object old_level, old_length; 1000 Lisp_Object old_level, old_length;
1001 char macroerror[50]; 1001 char macroerror[sizeof "After..kbd macro iterations: "
1002 + INT_STRLEN_BOUND (EMACS_INT)];
1002 1003
1003#ifdef HAVE_WINDOW_SYSTEM 1004#ifdef HAVE_WINDOW_SYSTEM
1004 if (display_hourglass_p) 1005 if (display_hourglass_p)
@@ -1010,7 +1011,7 @@ cmd_error (Lisp_Object data)
1010 if (executing_kbd_macro_iterations == 1) 1011 if (executing_kbd_macro_iterations == 1)
1011 sprintf (macroerror, "After 1 kbd macro iteration: "); 1012 sprintf (macroerror, "After 1 kbd macro iteration: ");
1012 else 1013 else
1013 sprintf (macroerror, "After %d kbd macro iterations: ", 1014 sprintf (macroerror, "After %"pI"d kbd macro iterations: ",
1014 executing_kbd_macro_iterations); 1015 executing_kbd_macro_iterations);
1015 } 1016 }
1016 else 1017 else
@@ -6463,11 +6464,15 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
6463 value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem)); 6464 value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
6464 else if (STRINGP (name_alist_or_stem)) 6465 else if (STRINGP (name_alist_or_stem))
6465 { 6466 {
6466 int len = SBYTES (name_alist_or_stem); 6467 char *buf;
6467 char *buf = (char *) alloca (len + 50); 6468 ptrdiff_t len = (SBYTES (name_alist_or_stem)
6468 sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem), 6469 + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT));
6469 XINT (symbol_int) + 1); 6470 USE_SAFE_ALLOCA;
6471 SAFE_ALLOCA (buf, char *, len);
6472 esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
6473 XINT (symbol_int) + 1);
6470 value = intern (buf); 6474 value = intern (buf);
6475 SAFE_FREE ();
6471 } 6476 }
6472 else if (name_table != 0 && name_table[symbol_num]) 6477 else if (name_table != 0 && name_table[symbol_num])
6473 value = intern (name_table[symbol_num]); 6478 value = intern (name_table[symbol_num]);
@@ -6483,7 +6488,7 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
6483 6488
6484 if (NILP (value)) 6489 if (NILP (value))
6485 { 6490 {
6486 char buf[20]; 6491 char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
6487 sprintf (buf, "key-%"pI"d", symbol_num); 6492 sprintf (buf, "key-%"pI"d", symbol_num);
6488 value = intern (buf); 6493 value = intern (buf);
6489 } 6494 }
@@ -10382,19 +10387,21 @@ give to the command you invoke, if it asks for an argument. */)
10382 char *newmessage; 10387 char *newmessage;
10383 int message_p = push_message (); 10388 int message_p = push_message ();
10384 int count = SPECPDL_INDEX (); 10389 int count = SPECPDL_INDEX ();
10390 ptrdiff_t newmessage_len, newmessage_alloc;
10391 USE_SAFE_ALLOCA;
10385 10392
10386 record_unwind_protect (pop_message_unwind, Qnil); 10393 record_unwind_protect (pop_message_unwind, Qnil);
10387 binding = Fkey_description (bindings, Qnil); 10394 binding = Fkey_description (bindings, Qnil);
10388 10395 newmessage_alloc =
10389 newmessage 10396 (sizeof "You can run the command `' with "
10390 = (char *) alloca (SCHARS (SYMBOL_NAME (function)) 10397 + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
10391 + SBYTES (binding) 10398 SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
10392 + 100); 10399 newmessage_len =
10393 sprintf (newmessage, "You can run the command `%s' with %s", 10400 esprintf (newmessage, "You can run the command `%s' with %s",
10394 SDATA (SYMBOL_NAME (function)), 10401 SDATA (SYMBOL_NAME (function)),
10395 SDATA (binding)); 10402 SDATA (binding));
10396 message2 (newmessage, 10403 message2 (newmessage,
10397 strlen (newmessage), 10404 newmessage_len,
10398 STRING_MULTIBYTE (binding)); 10405 STRING_MULTIBYTE (binding));
10399 if (NUMBERP (Vsuggest_key_bindings)) 10406 if (NUMBERP (Vsuggest_key_bindings))
10400 waited = sit_for (Vsuggest_key_bindings, 0, 2); 10407 waited = sit_for (Vsuggest_key_bindings, 0, 2);
@@ -10404,6 +10411,7 @@ give to the command you invoke, if it asks for an argument. */)
10404 if (!NILP (waited) && message_p) 10411 if (!NILP (waited) && message_p)
10405 restore_message (); 10412 restore_message ();
10406 10413
10414 SAFE_FREE ();
10407 unbind_to (count, Qnil); 10415 unbind_to (count, Qnil);
10408 } 10416 }
10409 } 10417 }
@@ -10633,7 +10641,9 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
10633 (void) 10641 (void)
10634{ 10642{
10635 Lisp_Object temp; 10643 Lisp_Object temp;
10636 XSETFASTINT (temp, command_loop_level + minibuf_level); 10644 /* Wrap around reliably on integer overflow. */
10645 EMACS_INT sum = (command_loop_level & INTMASK) + (minibuf_level & INTMASK);
10646 XSETINT (temp, sum);
10637 return temp; 10647 return temp;
10638} 10648}
10639 10649
diff --git a/src/keymap.c b/src/keymap.c
index 32b531daac4..4485080db21 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -2143,12 +2143,12 @@ spaces are put between sequence elements, etc. */)
2143 2143
2144 2144
2145char * 2145char *
2146push_key_description (register unsigned int c, register char *p, int force_multibyte) 2146push_key_description (EMACS_INT ch, char *p, int force_multibyte)
2147{ 2147{
2148 unsigned c2; 2148 int c, c2;
2149 2149
2150 /* Clear all the meaningless bits above the meta bit. */ 2150 /* Clear all the meaningless bits above the meta bit. */
2151 c &= meta_modifier | ~ - meta_modifier; 2151 c = ch & (meta_modifier | ~ - meta_modifier);
2152 c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier 2152 c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
2153 | meta_modifier | shift_modifier | super_modifier); 2153 | meta_modifier | shift_modifier | super_modifier);
2154 2154
@@ -2283,10 +2283,15 @@ around function keys and event symbols. */)
2283 { 2283 {
2284 if (NILP (no_angles)) 2284 if (NILP (no_angles))
2285 { 2285 {
2286 char *buffer 2286 char *buffer;
2287 = (char *) alloca (SBYTES (SYMBOL_NAME (key)) + 5); 2287 Lisp_Object result;
2288 sprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); 2288 USE_SAFE_ALLOCA;
2289 return build_string (buffer); 2289 SAFE_ALLOCA (buffer, char *,
2290 sizeof "<>" + SBYTES (SYMBOL_NAME (key)));
2291 esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key)));
2292 result = build_string (buffer);
2293 SAFE_FREE ();
2294 return result;
2290 } 2295 }
2291 else 2296 else
2292 return Fsymbol_name (key); 2297 return Fsymbol_name (key);
diff --git a/src/lisp.h b/src/lisp.h
index 99555118047..2f6ec38f228 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2895,6 +2895,16 @@ extern void syms_of_print (void);
2895/* Defined in doprnt.c */ 2895/* Defined in doprnt.c */
2896extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *, 2896extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *,
2897 va_list); 2897 va_list);
2898extern ptrdiff_t esprintf (char *, char const *, ...)
2899 ATTRIBUTE_FORMAT_PRINTF (2, 3);
2900extern ptrdiff_t esnprintf (char *, ptrdiff_t, char const *, ...)
2901 ATTRIBUTE_FORMAT_PRINTF (3, 4);
2902extern ptrdiff_t exprintf (char **, ptrdiff_t *, char const *, ptrdiff_t,
2903 char const *, ...)
2904 ATTRIBUTE_FORMAT_PRINTF (5, 6);
2905extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char const *, ptrdiff_t,
2906 char const *, va_list)
2907 ATTRIBUTE_FORMAT_PRINTF (5, 0);
2898 2908
2899/* Defined in lread.c. */ 2909/* Defined in lread.c. */
2900extern Lisp_Object Qvariable_documentation, Qstandard_input; 2910extern Lisp_Object Qvariable_documentation, Qstandard_input;
@@ -3186,7 +3196,7 @@ EXFUN (Fread_minibuffer, 2);
3186EXFUN (Feval_minibuffer, 2); 3196EXFUN (Feval_minibuffer, 2);
3187EXFUN (Fread_string, 5); 3197EXFUN (Fread_string, 5);
3188EXFUN (Fassoc_string, 3); 3198EXFUN (Fassoc_string, 3);
3189extern Lisp_Object get_minibuffer (int); 3199extern Lisp_Object get_minibuffer (EMACS_INT);
3190extern void init_minibuf_once (void); 3200extern void init_minibuf_once (void);
3191extern void syms_of_minibuf (void); 3201extern void syms_of_minibuf (void);
3192 3202
@@ -3250,7 +3260,7 @@ extern void force_auto_save_soon (void);
3250extern void init_keyboard (void); 3260extern void init_keyboard (void);
3251extern void syms_of_keyboard (void); 3261extern void syms_of_keyboard (void);
3252extern void keys_of_keyboard (void); 3262extern void keys_of_keyboard (void);
3253extern char *push_key_description (unsigned int, char *, int); 3263extern char *push_key_description (EMACS_INT, char *, int);
3254 3264
3255 3265
3256/* Defined in indent.c */ 3266/* Defined in indent.c */
diff --git a/src/minibuf.c b/src/minibuf.c
index eb564a10ec6..ad8f3ed8b86 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -49,7 +49,7 @@ static Lisp_Object minibuf_save_list;
49 49
50/* Depth in minibuffer invocations. */ 50/* Depth in minibuffer invocations. */
51 51
52int minibuf_level; 52EMACS_INT minibuf_level;
53 53
54/* The maximum length of a minibuffer history. */ 54/* The maximum length of a minibuffer history. */
55 55
@@ -772,10 +772,10 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
772 used for nonrecursive minibuffer invocations. */ 772 used for nonrecursive minibuffer invocations. */
773 773
774Lisp_Object 774Lisp_Object
775get_minibuffer (int depth) 775get_minibuffer (EMACS_INT depth)
776{ 776{
777 Lisp_Object tail, num, buf; 777 Lisp_Object tail, num, buf;
778 char name[24]; 778 char name[sizeof " *Minibuf-*" + INT_STRLEN_BOUND (EMACS_INT)];
779 779
780 XSETFASTINT (num, depth); 780 XSETFASTINT (num, depth);
781 tail = Fnthcdr (num, Vminibuffer_list); 781 tail = Fnthcdr (num, Vminibuffer_list);
@@ -787,7 +787,7 @@ get_minibuffer (int depth)
787 buf = Fcar (tail); 787 buf = Fcar (tail);
788 if (NILP (buf) || NILP (BVAR (XBUFFER (buf), name))) 788 if (NILP (buf) || NILP (BVAR (XBUFFER (buf), name)))
789 { 789 {
790 sprintf (name, " *Minibuf-%d*", depth); 790 sprintf (name, " *Minibuf-%"pI"d*", depth);
791 buf = Fget_buffer_create (build_string (name)); 791 buf = Fget_buffer_create (build_string (name));
792 792
793 /* Although the buffer's name starts with a space, undo should be 793 /* Although the buffer's name starts with a space, undo should be
diff --git a/src/window.h b/src/window.h
index 485734e907e..c6fa5e7a338 100644
--- a/src/window.h
+++ b/src/window.h
@@ -847,11 +847,11 @@ extern Lisp_Object echo_area_window;
847 847
848/* Depth in recursive edits. */ 848/* Depth in recursive edits. */
849 849
850extern int command_loop_level; 850extern EMACS_INT command_loop_level;
851 851
852/* Depth in minibuffer invocations. */ 852/* Depth in minibuffer invocations. */
853 853
854extern int minibuf_level; 854extern EMACS_INT minibuf_level;
855 855
856/* true if we should redraw the mode lines on the next redisplay. */ 856/* true if we should redraw the mode lines on the next redisplay. */
857 857