From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#9412: sprintf-related integer and memory overflow issues Date: Tue, 30 Aug 2011 15:42:58 -0700 Organization: UCLA Computer Science Department Message-ID: <4E5D6772.7060208@cs.ucla.edu> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: dough.gmane.org 1314744256 25419 80.91.229.12 (30 Aug 2011 22:44:16 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 30 Aug 2011 22:44:16 +0000 (UTC) To: 9412@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Aug 31 00:44:10 2011 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1QyX2L-0000nr-Nq for geb-bug-gnu-emacs@m.gmane.org; Wed, 31 Aug 2011 00:44:06 +0200 Original-Received: from localhost ([::1]:52202 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyX2L-0002ng-1e for geb-bug-gnu-emacs@m.gmane.org; Tue, 30 Aug 2011 18:44:05 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:49067) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyX2E-0002nG-9M for bug-gnu-emacs@gnu.org; Tue, 30 Aug 2011 18:44:02 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QyX29-0005yw-SA for bug-gnu-emacs@gnu.org; Tue, 30 Aug 2011 18:43:58 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:35072) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyX29-0005yg-Or for bug-gnu-emacs@gnu.org; Tue, 30 Aug 2011 18:43:53 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1QyX5C-0002oG-Ej; Tue, 30 Aug 2011 18:47:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 30 Aug 2011 22:47:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 9412 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.131474439710762 (code B ref -1); Tue, 30 Aug 2011 22:47:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 30 Aug 2011 22:46:37 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QyX4m-0002nV-15 for submit@debbugs.gnu.org; Tue, 30 Aug 2011 18:46:37 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QyX4g-0002nK-BB for submit@debbugs.gnu.org; Tue, 30 Aug 2011 18:46:33 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QyX1Y-0005t7-8U for submit@debbugs.gnu.org; Tue, 30 Aug 2011 18:43:20 -0400 Original-Received: from lists.gnu.org ([140.186.70.17]:35625) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyX1X-0005t1-Up for submit@debbugs.gnu.org; Tue, 30 Aug 2011 18:43:16 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:48756) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyX1S-0002ke-N0 for bug-gnu-emacs@gnu.org; Tue, 30 Aug 2011 18:43:15 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QyX1M-0005rV-Uz for bug-gnu-emacs@gnu.org; Tue, 30 Aug 2011 18:43:10 -0400 Original-Received: from smtp.cs.ucla.edu ([131.179.128.62]:57803) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyX1M-0005qz-1v for bug-gnu-emacs@gnu.org; Tue, 30 Aug 2011 18:43:04 -0400 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id B48CE39E80CF for ; Tue, 30 Aug 2011 15:43:01 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Original-Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Vp1YOx4uiLlL for ; Tue, 30 Aug 2011 15:42:59 -0700 (PDT) Original-Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 0195939E80DC for ; Tue, 30 Aug 2011 15:42:58 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.20) Gecko/20110805 Thunderbird/3.1.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Tue, 30 Aug 2011 18:47:02 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 1) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:50455 Archived-At: Package: Emacs Version: 24.0.50 Tags: patch Here's a patch to the Emacs trunk to fix some sprintf-related integer and memory overflow issues in Emacs proper. These bugs can cause the wrong integer to be displayed, or a buffer overrun in sprintf output, that sort of thing. Almost all the bugs can occur independently of whether --with-wide-int is used. The bugs range from unlikely to extremely unlikely in normal use (otherwise they would have been fixed already....). The patch is (I hope) routine. I plan to install this patch after some more internal testing. Here's an example bug. Arrange for the DISPLAY environment variable to use a host name that is longer than about 250 bytes. One way to do this is to set DISPLAY=3D'127.0.00000000000000.1:10.0' (but use 250 more = zeros). Run Emacs under X, and then arrange for the X server's connection to be dropped. The Emacs function x_io_error_quitter will do this: char buf[256]; sprintf (buf, "Connection lost to X server `%s'", DisplayString (disp= lay)); and the long host name will overrun BUF. =3D=3D=3D modified file 'src/ChangeLog' --- src/ChangeLog 2011-08-30 18:15:53 +0000 +++ src/ChangeLog 2011-08-30 21:16:49 +0000 @@ -1,3 +1,109 @@ +2011-08-30 Paul Eggert + + 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. + + * dbusbind.c (signature_cat): New function. + (xd_signature, Fdbus_register_signal): + Do not overrun buffer; instead, report string overflow. + + * dispnew.c (add_window_display_history): Don't overrun buffer. + Truncate instead; this is OK since it's just a log. + + * editfns.c (Fcurrent_time_zone): Don't overrun buffer + even if the time zone offset is outlandishly large. + Don't mishandle offset =3D=3D INT_MIN. + + * emacs.c (main) [NS_IMPL_COCOA]: Don't overrun buffer + when creating daemon; the previous buffer-overflow check was incorrect. + + * eval.c (verror): Simplify by rewriting in terms of evxprintf, + which has the guts of the old verror function. + + * filelock.c (lock_file_1, lock_file): Don't blindly alloca long name; + use SAFE_ALLOCA instead. Use esprintf to avoid int-overflow issues. + + * font.c: Include , for DBL_MAX_10_EXP. + (font_unparse_xlfd): Don't blindly alloca long strings. + Don't assume XINT result fits in int, or that XFLOAT_DATA * 10 + fits in int, when using sprintf. Use single snprintf to count + length of string rather than counting it via multiple sprintfs; + that's simpler and more reliable. + (APPEND_SPRINTF): New macro. + (font_unparse_fcname): Use it to avoid sprintf buffer overrun. + (generate_otf_features) [0 && HAVE_LIBOTF]: Use esprintf, not + sprintf, in case result does not fit in int. + + * fontset.c (num_auto_fontsets): Now printmax_t, not int. + (fontset_from_font): Print it. + + * frame.c (tty_frame_count): Now printmax_t, not int. + (make_terminal_frame, set_term_frame_name): Print it. + (x_report_frame_params): In X, window IDs are unsigned long, + not signed long, so print them as unsigned. + (validate_x_resource_name): Check for implausibly long names, + and don't assume name length fits in 'int'. + (x_get_resource_string): Don't blindly alloca invocation name; + use SAFE_ALLOCA. Use esprintf, not sprintf, in case result does + not fit in int. + + * gtkutil.c: Include , for DBL_MAX_10_EXP. + (xg_check_special_colors, xg_set_geometry): + Make sprintf buffers a bit bigger, to avoid potential buffer overrun. + + * lread.c (dir_warning): Don't blindly alloca buffer; use SAFE_ALLOCA. + Use esprintf, not sprintf, in case result does not fit in int. + + * macros.c (executing_kbd_macro_iterations): Now EMACS_INT, not int. + (Fend_kbd_macro): Don't mishandle MOST_NEGATIVE_FIXNUM by treating + it as a large positive number. + (Fexecute_kbd_macro): Don't assume repeat count fits in int. + * macros.h (executing_kbd_macro_iterations): Now EMACS_INT, not int. + + * nsterm.m ((NSSize)windowWillResize): Use esprintf, not sprintf, + in case result does not fit in int. + + * print.c (float_to_string): Detect width overflow more reliably. + (print_object): Make sprintf buffer a bit bigger, to avoid potential + buffer overrun. Don't assume list length fits in 'int'. Treat + print length of 0 as 0, not as infinity; to be consistent with other + uses of print length in this function. Don't overflow print length + index. Don't assume hash table size fits in 'long', or that + vectorlike size fits in 'unsigned long'. + + * process.c (make_process): Use printmax_t, not int, to format + process-name gensyms. + + * term.c (produce_glyphless_glyph): Make sprintf buffer a bit bigger + to avoid potential buffer overrun. + + * xfaces.c (x_update_menu_appearance): Don't overrun buffer + if X resource line is longer than 512 bytes. + + * xfns.c (x_window): Make sprintf buffer a bit bigger + to avoid potential buffer overrun. + + * xterm.c (x_io_error_quitter): Don't overrun sprintf buffer. + + * xterm.h (x_check_errors): Add ATTRIBUTE_FORMAT_PRINTF. + 2011-08-30 Eli Zaretskii =20 * image.c (x_bitmap_pixmap): Cast to int to avoid compiler warnings. =3D=3D=3D modified file 'src/dbusbind.c' --- src/dbusbind.c 2011-06-24 21:25:22 +0000 +++ src/dbusbind.c 2011-08-30 22:02:56 +0000 @@ -259,6 +259,18 @@ } \ while (0) =20 +/* Append to SIGNATURE a copy of X, making sure SIGNATURE does + not become too long. */ +static void +signature_cat (char *signature, char const *x) +{ + ptrdiff_t siglen =3D strlen (signature); + ptrdiff_t xlen =3D strlen (x); + if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <=3D siglen) + string_overflow (); + strcat (signature, x); +} + /* Compute SIGNATURE of OBJECT. It must have a form that it can be used in dbus_message_iter_open_container. DTYPE is the DBusType the object is related to. It is passed as argument, because it @@ -271,6 +283,7 @@ { unsigned int subtype; Lisp_Object elt; + char const *subsig; char x[DBUS_MAXIMUM_SIGNATURE_LENGTH]; =20 elt =3D object; @@ -328,12 +341,13 @@ if (NILP (elt)) { subtype =3D DBUS_TYPE_STRING; - strcpy (x, DBUS_TYPE_STRING_AS_STRING); + subsig =3D DBUS_TYPE_STRING_AS_STRING; } else { subtype =3D XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); + subsig =3D x; } =20 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the @@ -342,7 +356,7 @@ if ((subtype =3D=3D DBUS_TYPE_SIGNATURE) && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt))) && NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) - strcpy (x, SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt)))); + subsig =3D SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt))); =20 while (!NILP (elt)) { @@ -351,7 +365,10 @@ elt =3D CDR_SAFE (XD_NEXT_VALUE (elt)); } =20 - sprintf (signature, "%c%s", dtype, x); + if (esnprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH, + "%c%s", dtype, subsig) + =3D=3D DBUS_MAXIMUM_SIGNATURE_LENGTH - 1) + string_overflow (); break; =20 case DBUS_TYPE_VARIANT: @@ -383,10 +400,10 @@ { subtype =3D XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - strcat (signature, x); + signature_cat (signature, x); elt =3D CDR_SAFE (XD_NEXT_VALUE (elt)); } - strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); + signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); break; =20 case DBUS_TYPE_DICT_ENTRY: @@ -407,7 +424,7 @@ elt =3D XD_NEXT_VALUE (elt); subtype =3D XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - strcat (signature, x); + signature_cat (signature, x); =20 if (!XD_BASIC_DBUS_TYPE (subtype)) wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt))); @@ -416,14 +433,14 @@ elt =3D CDR_SAFE (XD_NEXT_VALUE (elt)); subtype =3D XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - strcat (signature, x); + signature_cat (signature, x); =20 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) wrong_type_argument (intern ("D-Bus"), CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt)))); =20 /* Closing signature. */ - strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); + signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); break; =20 default: @@ -2026,7 +2043,7 @@ DBusConnection *connection; ptrdiff_t i; char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; - char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; + int rulelen; DBusError derror; =20 /* Check parameters. */ @@ -2071,34 +2088,32 @@ connection =3D xd_initialize (bus, TRUE); =20 /* Create a rule to receive related signals. */ - sprintf (rule, - "type=3D'signal',interface=3D'%s',member=3D'%s'", - SDATA (interface), - SDATA (signal)); + rulelen =3D esnprintf (rule, sizeof rule, + "type=3D'signal',interface=3D'%s',member=3D'%s'", + SDATA (interface), + SDATA (signal)); =20 /* Add unique name and path to the rule if they are non-nil. */ if (!NILP (uname)) - { - sprintf (x, ",sender=3D'%s'", SDATA (uname)); - strcat (rule, x); - } + rulelen +=3D esnprintf (rule + rulelen, sizeof rule - rulelen, + ",sender=3D'%s'", SDATA (uname)); =20 if (!NILP (path)) - { - sprintf (x, ",path=3D'%s'", SDATA (path)); - strcat (rule, x); - } + rulelen +=3D esnprintf (rule + rulelen, sizeof rule - rulelen, + ",path=3D'%s'", SDATA (path)); =20 /* Add arguments to the rule if they are non-nil. */ for (i =3D 6; i < nargs; ++i) if (!NILP (args[i])) { CHECK_STRING (args[i]); - sprintf (x, ",arg%"pD"d=3D'%s'", i - 6, - SDATA (args[i])); - strcat (rule, x); + rulelen +=3D esnprintf (rule + rulelen, sizeof rule - rulelen, + ",arg%"pD"d=3D'%s'", i - 6, SDATA (args[i])); } =20 + if (rulelen =3D=3D sizeof rule - 1) + string_overflow (); + /* Add the rule to the bus. */ dbus_error_init (&derror); dbus_bus_add_match (connection, rule, &derror); =3D=3D=3D modified file 'src/dispnew.c' --- src/dispnew.c 2011-08-24 21:20:36 +0000 +++ src/dispnew.c 2011-08-29 15:51:23 +0000 @@ -272,15 +272,16 @@ buf =3D redisplay_history[history_idx].trace; ++history_idx; =20 - sprintf (buf, "%"pMu": window %p (`%s')%s\n", - history_tick++, - w, - ((BUFFERP (w->buffer) - && STRINGP (BVAR (XBUFFER (w->buffer), name))) - ? SSDATA (BVAR (XBUFFER (w->buffer), name)) - : "???"), - paused_p ? " ***paused***" : ""); - strcat (buf, msg); + esnprintf (buf, sizeof redisplay_history[0].trace, + "%"pMu": window %p (`%s')%s\n%s", + history_tick++, + w, + ((BUFFERP (w->buffer) + && STRINGP (BVAR (XBUFFER (w->buffer), name))) + ? SSDATA (BVAR (XBUFFER (w->buffer), name)) + : "???"), + paused_p ? " ***paused***" : "", + msg); } =20 =20 =3D=3D=3D modified file 'src/doprnt.c' --- src/doprnt.c 2011-07-07 02:14:52 +0000 +++ src/doprnt.c 2011-08-29 15:43:34 +0000 @@ -70,9 +70,9 @@ %character =20 where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and len= gth - is empty or l or the value of the pI macro. Also, %% in a format - stands for a single % in the output. A % that does not introduce a - valid %-sequence causes undefined behavior. + is empty or l or the value of the pD or pI or pMd (sans "d") macros. + Also, %% in a format stands for a single % in the output. A % that + does not introduce a valid %-sequence causes undefined behavior. =20 The + flag character inserts a + before any positive number, while a = space inserts a space before any positive number; these flags only affect %= d, %o, @@ -85,8 +85,10 @@ modifier: it is supported for %d, %o, and %x conversions of integral arguments, must immediately precede the conversion specifier, and mea= ns that the respective argument is to be treated as `long int' or `unsigned l= ong - int'. Similarly, the value of the pI macro means to use EMACS_INT or - EMACS_UINT and the empty length modifier means `int' or `unsigned int= '. + int'. Similarly, the value of the pD macro means to use ptrdiff_t, + the value of the pI macro means to use EMACS_INT or EMACS_UINT, the + value of the pMd etc. macros means to use intmax_t or uintmax_t, + and the empty length modifier means `int' or `unsigned int'. =20 The width specifier supplies a lower limit for the length of the prin= ted representation. The padding, if any, normally goes on the left, but = it goes @@ -173,8 +175,17 @@ { ptrdiff_t size_bound =3D 0; EMACS_INT width; /* Columns occupied by STRING on display. */ - int long_flag =3D 0; - int pIlen =3D sizeof pI - 1; + enum { + pDlen =3D sizeof pD - 1, + pIlen =3D sizeof pI - 1, + pMlen =3D sizeof pMd - 2 + }; + enum { + no_modifier, long_modifier, pD_modifier, pI_modifier, pM_modifier + } length_modifier =3D no_modifier; + static char const modifier_len[] =3D { 0, 1, pDlen, pIlen, pMlen }; + int maxmlen =3D max (max (1, pDlen), max (pIlen, pMlen)); + int mlen; =20 fmt++; /* Copy this one %-spec into fmtcpy. */ @@ -213,19 +224,26 @@ fmt++; } =20 - if (0 < pIlen && pIlen <=3D format_end - fmt - && memcmp (fmt, pI, pIlen) =3D=3D 0) - { - long_flag =3D 2; - memcpy (string, fmt + 1, pIlen); - string +=3D pIlen; - fmt +=3D pIlen; - } - else if (fmt < format_end && *fmt =3D=3D 'l') - { - long_flag =3D 1; - *string++ =3D *++fmt; - } + /* Check for the length modifiers in textual length order, so + that longer modifiers override shorter ones. */ + for (mlen =3D 1; mlen <=3D maxmlen; mlen++) + { + if (format_end - fmt < mlen) + break; + if (mlen =3D=3D 1 && *fmt =3D=3D 'l') + length_modifier =3D long_modifier; + if (mlen =3D=3D pDlen && memcmp (fmt, pD, pDlen) =3D=3D 0) + length_modifier =3D pD_modifier; + if (mlen =3D=3D pIlen && memcmp (fmt, pI, pIlen) =3D=3D 0) + length_modifier =3D pI_modifier; + if (mlen =3D=3D pMlen && memcmp (fmt, pMd, pMlen) =3D=3D 0) + length_modifier =3D pM_modifier; + } + + mlen =3D modifier_len[length_modifier]; + memcpy (string, fmt + 1, mlen); + string +=3D mlen; + fmt +=3D mlen; *string =3D 0; =20 /* Make the size bound large enough to handle floating point formats @@ -252,55 +270,78 @@ /* case 'b': */ case 'l': case 'd': - { - int i; - long l; - - if (1 < long_flag) - { - EMACS_INT ll =3D va_arg (ap, EMACS_INT); - sprintf (sprintf_buffer, fmtcpy, ll); - } - else if (long_flag) - { - l =3D va_arg(ap, long); - sprintf (sprintf_buffer, fmtcpy, l); - } - else - { - i =3D va_arg(ap, int); - sprintf (sprintf_buffer, fmtcpy, i); - } - /* Now copy into final output, truncating as necessary. */ - string =3D sprintf_buffer; - goto doit; - } + switch (length_modifier) + { + case no_modifier: + { + int v =3D va_arg (ap, int); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case long_modifier: + { + long v =3D va_arg (ap, long); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pD_modifier: + signed_pD_modifier: + { + ptrdiff_t v =3D va_arg (ap, ptrdiff_t); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pI_modifier: + { + EMACS_INT v =3D va_arg (ap, EMACS_INT); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pM_modifier: + { + intmax_t v =3D va_arg (ap, intmax_t); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + } + /* Now copy into final output, truncating as necessary. */ + string =3D sprintf_buffer; + goto doit; =20 case 'o': case 'x': - { - unsigned u; - unsigned long ul; - - if (1 < long_flag) - { - EMACS_UINT ull =3D va_arg (ap, EMACS_UINT); - sprintf (sprintf_buffer, fmtcpy, ull); - } - else if (long_flag) - { - ul =3D va_arg(ap, unsigned long); - sprintf (sprintf_buffer, fmtcpy, ul); - } - else - { - u =3D va_arg(ap, unsigned); - sprintf (sprintf_buffer, fmtcpy, u); - } - /* Now copy into final output, truncating as necessary. */ - string =3D sprintf_buffer; - goto doit; - } + switch (length_modifier) + { + case no_modifier: + { + unsigned v =3D va_arg (ap, unsigned); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case long_modifier: + { + unsigned long v =3D va_arg (ap, unsigned long); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pD_modifier: + goto signed_pD_modifier; + case pI_modifier: + { + EMACS_UINT v =3D va_arg (ap, EMACS_UINT); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pM_modifier: + { + uintmax_t v =3D va_arg (ap, uintmax_t); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + } + /* Now copy into final output, truncating as necessary. */ + string =3D sprintf_buffer; + goto doit; =20 case 'f': case 'e': @@ -426,3 +467,82 @@ SAFE_FREE (); return bufptr - buffer; } + +/* Format to an unbounded buffer BUF. This is like sprintf, except it + is not limited to returning an 'int' so it doesn't have a silly 2 + GiB limit on typical 64-bit hosts. However, it is limited to the + Emacs-style formats that doprnt supports. + + Return the number of bytes put into BUF, excluding the terminating + '\0'. */ +ptrdiff_t +esprintf (char *buf, char const *format, ...) +{ + ptrdiff_t nbytes; + va_list ap; + va_start (ap, format); + nbytes =3D doprnt (buf, TYPE_MAXIMUM (ptrdiff_t), format, 0, ap); + va_end (ap); + return nbytes; +} + +/* Format to a buffer BUF of positive size BUFSIZE. This is like + snprintf, except it is not limited to returning an 'int' so it + doesn't have a silly 2 GiB limit on typical 64-bit hosts. However, + it is limited to the Emacs-style formats that doprnt supports, and + BUFSIZE must be positive. + + Return the number of bytes put into BUF, excluding the terminating + '\0'. Unlike snprintf, always return a nonnegative value less than + BUFSIZE; if the output is truncated, return BUFSIZE - 1, which is + the length of the truncated output. */ +ptrdiff_t +esnprintf (char *buf, ptrdiff_t bufsize, char const *format, ...) +{ + ptrdiff_t nbytes; + va_list ap; + va_start (ap, format); + nbytes =3D doprnt (buf, bufsize, format, 0, ap); + va_end (ap); + return nbytes; +} + +/* Format to buffer *BUF of positive size *BUFSIZE, reallocating *BUF + and updating *BUFSIZE if the buffer is too small, and otherwise + behaving line esprintf. When reallocating, free *BUF unless it is + equal to NONHEAPBUF, and if BUFSIZE_MAX is nonnegative then signal + memory exhaustion instead of growing the buffer size past + BUFSIZE_MAX. */ +ptrdiff_t +exprintf (char **buf, ptrdiff_t *bufsize, + char const *nonheapbuf, ptrdiff_t bufsize_max, + char const *format, ...) +{ + ptrdiff_t nbytes; + va_list ap; + va_start (ap, format); + nbytes =3D evxprintf (buf, bufsize, nonheapbuf, bufsize_max, format, a= p); + va_end (ap); + return nbytes; +} + +/* Act like exprintf, except take a va_list. */ +ptrdiff_t +evxprintf (char **buf, ptrdiff_t *bufsize, + char const *nonheapbuf, ptrdiff_t bufsize_max, + char const *format, va_list ap) +{ + for (;;) + { + ptrdiff_t nbytes; + va_list ap_copy; + va_copy (ap_copy, ap); + nbytes =3D doprnt (*buf, *bufsize, format, 0, ap_copy); + va_end (ap_copy); + if (nbytes < *bufsize - 1) + return nbytes; + if (*buf !=3D nonheapbuf) + xfree (*buf); + *buf =3D xpalloc (NULL, bufsize, 1, bufsize_max, 1); + } +} =3D=3D=3D modified file 'src/editfns.c' --- src/editfns.c 2011-08-19 06:11:38 +0000 +++ src/editfns.c 2011-08-29 15:53:21 +0000 @@ -2014,7 +2014,7 @@ { int offset =3D tm_diff (t, &gmt); char *s =3D 0; - char buf[6]; + char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; =20 #ifdef HAVE_TM_ZONE if (t->tm_zone) @@ -2029,7 +2029,8 @@ if (!s) { /* No local time zone name is available; use "+-NNNN" instead. */ - int am =3D (offset < 0 ? -offset : offset) / 60; + int m =3D offset / 60; + int am =3D offset < 0 ? - m : m; sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60); s =3D buf; } =3D=3D=3D modified file 'src/emacs.c' --- src/emacs.c 2011-08-05 02:19:34 +0000 +++ src/emacs.c 2011-08-29 15:56:20 +0000 @@ -1068,15 +1068,17 @@ if (!dname_arg || !strchr (dname_arg, '\n')) { /* In orig, child: now exec w/special daemon name. */ char fdStr[80]; + int fdStrlen =3D + snprintf (fdStr, sizeof fdStr, + "--daemon=3D\n%d,%d\n%s", daemon_pipe[0], + daemon_pipe[1], dname_arg ? dname_arg : ""); =20 - if (dname_arg && strlen (dname_arg) > 70) + if (! (0 <=3D fdStrlen && fdStrlen < sizeof fdStr)) { fprintf (stderr, "daemon: child name too long\n"); exit (1); } =20 - sprintf (fdStr, "--daemon=3D\n%d,%d\n%s", daemon_pipe[0], - daemon_pipe[1], dname_arg ? dname_arg : ""); argv[skip_args] =3D fdStr; =20 execv (argv[0], argv); =3D=3D=3D modified file 'src/eval.c' --- src/eval.c 2011-08-24 21:20:36 +0000 +++ src/eval.c 2011-08-29 16:01:33 +0000 @@ -1951,35 +1951,11 @@ char buf[4000]; ptrdiff_t size =3D sizeof buf; ptrdiff_t size_max =3D STRING_BYTES_BOUND + 1; - char const *m_end =3D m + strlen (m); char *buffer =3D buf; ptrdiff_t used; Lisp_Object string; =20 - while (1) - { - va_list ap_copy; - va_copy (ap_copy, ap); - used =3D doprnt (buffer, size, m, m_end, ap_copy); - va_end (ap_copy); - - /* Note: the -1 below is because `doprnt' returns the number of by= tes - 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 <=3D size_max / 2) - size *=3D 2; - else if (size < size_max) - size =3D size_max; - else - break; /* and leave the message truncated */ - - if (buffer !=3D buf) - xfree (buffer); - buffer =3D (char *) xmalloc (size); - } - + used =3D evxprintf (&buffer, &size, buf, size_max, m, ap); string =3D make_string (buffer, used); if (buffer !=3D buf) xfree (buffer); =3D=3D=3D modified file 'src/filelock.c' --- src/filelock.c 2011-07-07 21:52:44 +0000 +++ src/filelock.c 2011-08-29 16:48:19 +0000 @@ -341,6 +341,9 @@ const char *user_name; const char *host_name; char *lock_info_str; + ptrdiff_t lock_info_size; + int symlink_errno; + USE_SAFE_ALLOCA; =20 /* Call this first because it can GC. */ boot =3D get_boot_time (); @@ -353,17 +356,14 @@ host_name =3D SSDATA (Fsystem_name ()); else host_name =3D ""; - lock_info_str =3D (char *)alloca (strlen (user_name) + strlen (host_na= me) - + 2 * INT_STRLEN_BOUND (printmax_t) - + sizeof "@.:"); + lock_info_size =3D (strlen (user_name) + strlen (host_name) + + 2 * INT_STRLEN_BOUND (printmax_t) + + sizeof "@.:"); + SAFE_ALLOCA (lock_info_str, char *, lock_info_size); pid =3D getpid (); =20 - if (boot) - sprintf (lock_info_str, "%s@%s.%"pMd":%"pMd, - user_name, host_name, pid, boot); - else - sprintf (lock_info_str, "%s@%s.%"pMd, - user_name, host_name, pid); + esprintf (lock_info_str, boot ? "%s@%s.%"pMd":%"pMd : "%s@%s.%"pMd, + user_name, host_name, pid, boot); =20 err =3D symlink (lock_info_str, lfname); if (errno =3D=3D EEXIST && force) @@ -372,6 +372,9 @@ err =3D symlink (lock_info_str, lfname); } =20 + symlink_errno =3D errno; + SAFE_FREE (); + errno =3D symlink_errno; return err =3D=3D 0; } =20 @@ -541,9 +544,11 @@ { register Lisp_Object attack, orig_fn, encoded_fn; register char *lfname, *locker; + ptrdiff_t locker_size; lock_info_type lock_info; printmax_t pid; struct gcpro gcpro1; + USE_SAFE_ALLOCA; =20 /* Don't do locking while dumping Emacs. Uncompressing wtmp files uses call-process, which does not work @@ -580,15 +585,17 @@ return; =20 /* Else consider breaking the lock */ - locker =3D (char *) alloca (strlen (lock_info.user) + strlen (lock_inf= o.host) - + INT_STRLEN_BOUND (printmax_t) - + sizeof "@ (pid )"); + locker_size =3D (strlen (lock_info.user) + strlen (lock_info.host) + + INT_STRLEN_BOUND (printmax_t) + + sizeof "@ (pid )"); + SAFE_ALLOCA (locker, char *, locker_size); pid =3D lock_info.pid; - sprintf (locker, "%s@%s (pid %"pMd")", - lock_info.user, lock_info.host, pid); + esprintf (locker, "%s@%s (pid %"pMd")", + lock_info.user, lock_info.host, pid); FREE_LOCK_INFO (lock_info); =20 attack =3D call2 (intern ("ask-user-about-lock"), fn, build_string (lo= cker)); + SAFE_FREE (); if (!NILP (attack)) /* User says take the lock */ { =3D=3D=3D modified file 'src/font.c' --- src/font.c 2011-07-10 08:20:10 +0000 +++ src/font.c 2011-08-29 20:57:42 +0000 @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see . */ =20 #include +#include #include #include #include @@ -1180,7 +1181,7 @@ char *p; const char *f[XLFD_REGISTRY_INDEX + 1]; Lisp_Object val; - int i, j, len =3D 0; + int i, j, len; =20 font_assert (FONTP (font)); =20 @@ -1195,9 +1196,9 @@ if (NILP (val)) { if (j =3D=3D XLFD_REGISTRY_INDEX) - f[j] =3D "*-*", len +=3D 4; + f[j] =3D "*-*"; else - f[j] =3D "*", len +=3D 2; + f[j] =3D "*"; } else { @@ -1207,21 +1208,15 @@ && ! strchr (SSDATA (val), '-')) { /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */ - if (SDATA (val)[SBYTES (val) - 1] =3D=3D '*') - { - f[j] =3D p =3D alloca (SBYTES (val) + 3); - sprintf (p, "%s-*", SDATA (val)); - len +=3D SBYTES (val) + 3; - } - else - { - f[j] =3D p =3D alloca (SBYTES (val) + 4); - sprintf (p, "%s*-*", SDATA (val)); - len +=3D SBYTES (val) + 4; - } + ptrdiff_t alloc =3D SBYTES (val) + 4; + if (nbytes <=3D alloc) + return -1; + f[j] =3D p =3D alloca (alloc); + sprintf (p, "%s%s-*", SDATA (val), + "*" + (SDATA (val)[SBYTES (val) - 1] =3D=3D '*')); } else - f[j] =3D SSDATA (val), len +=3D SBYTES (val) + 1; + f[j] =3D SSDATA (val); } } =20 @@ -1230,11 +1225,11 @@ { val =3D font_style_symbolic (font, i, 0); if (NILP (val)) - f[j] =3D "*", len +=3D 2; + f[j] =3D "*"; else { val =3D SYMBOL_NAME (val); - f[j] =3D SSDATA (val), len +=3D SBYTES (val) + 1; + f[j] =3D SSDATA (val); } } =20 @@ -1242,64 +1237,62 @@ font_assert (NUMBERP (val) || NILP (val)); if (INTEGERP (val)) { - i =3D XINT (val); - if (i <=3D 0) - i =3D pixel_size; - if (i > 0) + EMACS_INT v =3D XINT (val); + if (v <=3D 0) + v =3D pixel_size; + if (v > 0) { - f[XLFD_PIXEL_INDEX] =3D p =3D alloca (22); - len +=3D sprintf (p, "%d-*", i) + 1; + f[XLFD_PIXEL_INDEX] =3D p =3D + alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT)); + sprintf (p, "%"pI"d-*", v); } else - f[XLFD_PIXEL_INDEX] =3D "*-*", len +=3D 4; + f[XLFD_PIXEL_INDEX] =3D "*-*"; } else if (FLOATP (val)) { - i =3D XFLOAT_DATA (val) * 10; - f[XLFD_PIXEL_INDEX] =3D p =3D alloca (12); - len +=3D sprintf (p, "*-%d", i) + 1; + double v =3D XFLOAT_DATA (val) * 10; + f[XLFD_PIXEL_INDEX] =3D p =3D alloca (sizeof "*-" + 1 + DBL_MAX_10= _EXP + 1); + sprintf (p, "*-%.0f", v); } else - f[XLFD_PIXEL_INDEX] =3D "*-*", len +=3D 4; + f[XLFD_PIXEL_INDEX] =3D "*-*"; =20 if (INTEGERP (AREF (font, FONT_DPI_INDEX))) { - i =3D XINT (AREF (font, FONT_DPI_INDEX)); - f[XLFD_RESX_INDEX] =3D p =3D alloca (22); - len +=3D sprintf (p, "%d-%d", i, i) + 1; + EMACS_INT v =3D XINT (AREF (font, FONT_DPI_INDEX)); + f[XLFD_RESX_INDEX] =3D p =3D + alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT)); + sprintf (p, "%"pI"d-%"pI"d", v, v); } else - f[XLFD_RESX_INDEX] =3D "*-*", len +=3D 4; + f[XLFD_RESX_INDEX] =3D "*-*"; if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) { - int spacing =3D XINT (AREF (font, FONT_SPACING_INDEX)); + EMACS_INT spacing =3D XINT (AREF (font, FONT_SPACING_INDEX)); =20 f[XLFD_SPACING_INDEX] =3D (spacing <=3D FONT_SPACING_PROPORTIONAL = ? "p" : spacing <=3D FONT_SPACING_DUAL ? "d" : spacing <=3D FONT_SPACING_MONO ? "m" : "c"); - len +=3D 2; } else - f[XLFD_SPACING_INDEX] =3D "*", len +=3D 2; + f[XLFD_SPACING_INDEX] =3D "*"; if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) { - f[XLFD_AVGWIDTH_INDEX] =3D p =3D alloca (22); - len +=3D sprintf (p, "%"pI"d", - XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1; + f[XLFD_AVGWIDTH_INDEX] =3D p =3D alloca (INT_BUFSIZE_BOUND (EMACS_= INT)); + sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX))); } else - f[XLFD_AVGWIDTH_INDEX] =3D "*", len +=3D 2; - len++; /* for terminating '\0'. */ - if (len >=3D nbytes) - return -1; - return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", + f[XLFD_AVGWIDTH_INDEX] =3D "*"; + len =3D snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX], f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX], f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX], f[XLFD_REGISTRY_INDEX]); + return len < nbytes ? len : -1; } =20 /* Parse NAME (null terminated) and store information in FONT @@ -1553,23 +1546,19 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int n= bytes) { Lisp_Object family, foundry; - Lisp_Object tail, val; + Lisp_Object val; int point_size; int i; - ptrdiff_t len =3D 1; char *p; + char *lim; Lisp_Object styles[3]; const char *style_names[3] =3D { "weight", "slant", "width" }; - char work[256]; =20 family =3D AREF (font, FONT_FAMILY_INDEX); if (! NILP (family)) { if (SYMBOLP (family)) - { - family =3D SYMBOL_NAME (family); - len +=3D SBYTES (family); - } + family =3D SYMBOL_NAME (family); else family =3D Qnil; } @@ -1580,7 +1569,6 @@ if (XINT (val) !=3D 0) pixel_size =3D XINT (val); point_size =3D -1; - len +=3D 21; /* for ":pixelsize=3DNUM" */ } else { @@ -1588,80 +1576,54 @@ abort (); pixel_size =3D -1; point_size =3D (int) XFLOAT_DATA (val); - len +=3D 11; /* for "-NUM" */ } =20 foundry =3D AREF (font, FONT_FOUNDRY_INDEX); if (! NILP (foundry)) { if (SYMBOLP (foundry)) - { - foundry =3D SYMBOL_NAME (foundry); - len +=3D 9 + SBYTES (foundry); /* ":foundry=3DNAME" */ - } + foundry =3D SYMBOL_NAME (foundry); else foundry =3D Qnil; } =20 for (i =3D 0; i < 3; i++) - { - styles[i] =3D font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0)= ; - if (! NILP (styles[i])) - len +=3D sprintf (work, ":%s=3D%s", style_names[i], - SDATA (SYMBOL_NAME (styles[i]))); - } - - if (INTEGERP (AREF (font, FONT_DPI_INDEX))) - len +=3D sprintf (work, ":dpi=3D%"pI"d", XINT (AREF (font, FONT_DPI_= INDEX))); - if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) - len +=3D strlen (":spacing=3D100"); - if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) - len +=3D strlen (":scalable=3Dfalse"); /* or ":scalable=3Dtrue" */ - for (tail =3D AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail =3D XC= DR (tail)) - { - Lisp_Object key =3D XCAR (XCAR (tail)), value =3D XCDR (XCAR (tail= )); - - len +=3D SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY=3D */ - if (STRINGP (value)) - len +=3D SBYTES (value); - else if (INTEGERP (value)) - len +=3D sprintf (work, "%"pI"d", XINT (value)); - else if (SYMBOLP (value)) - len +=3D (NILP (value) ? 5 : 4); /* for "false" or "true" */ - } - - if (len > nbytes) - return -1; + styles[i] =3D font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0); + p =3D name; + lim =3D name + nbytes; +# define APPEND_SNPRINTF(args) \ + do { \ + int len =3D snprintf args; \ + if (! (0 <=3D len && len < lim - p)) \ + return -1; \ + p +=3D len; \ + } while (0) if (! NILP (family)) - p +=3D sprintf (p, "%s", SDATA (family)); + APPEND_SNPRINTF ((p, lim - p, "%s", SSDATA (family))); if (point_size > 0) - { - if (p =3D=3D name) - p +=3D sprintf (p, "%d", point_size); - else - p +=3D sprintf (p, "-%d", point_size); - } + APPEND_SNPRINTF ((p, lim - p, "-%d" + (p =3D=3D name), point_size)); else if (pixel_size > 0) - p +=3D sprintf (p, ":pixelsize=3D%d", pixel_size); + APPEND_SNPRINTF ((p, lim - p, ":pixelsize=3D%d", pixel_size)); if (! NILP (AREF (font, FONT_FOUNDRY_INDEX))) - p +=3D sprintf (p, ":foundry=3D%s", - SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX)))); + APPEND_SNPRINTF ((p, lim - p, ":foundry=3D%s", + SSDATA (SYMBOL_NAME (AREF (font, + FONT_FOUNDRY_INDEX))))); for (i =3D 0; i < 3; i++) if (! NILP (styles[i])) - p +=3D sprintf (p, ":%s=3D%s", style_names[i], - SDATA (SYMBOL_NAME (styles[i]))); + APPEND_SNPRINTF ((p, lim - p, ":%s=3D%s", style_names[i], + SSDATA (SYMBOL_NAME (styles[i])))); if (INTEGERP (AREF (font, FONT_DPI_INDEX))) - p +=3D sprintf (p, ":dpi=3D%"pI"d", XINT (AREF (font, FONT_DPI_INDEX= ))); + APPEND_SNPRINTF ((p, lim - p, ":dpi=3D%"pI"d", + XINT (AREF (font, FONT_DPI_INDEX)))); if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) - p +=3D sprintf (p, ":spacing=3D%"pI"d", XINT (AREF (font, FONT_SPACI= NG_INDEX))); + APPEND_SNPRINTF ((p, lim - p, ":spacing=3D%"pI"d", + XINT (AREF (font, FONT_SPACING_INDEX)))); if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) - { - if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) =3D=3D 0) - p +=3D sprintf (p, ":scalable=3Dtrue"); - else - p +=3D sprintf (p, ":scalable=3Dfalse"); - } + APPEND_SNPRINTF ((p, lim - p, + (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) =3D=3D 0 + ? ":scalable=3Dtrue" + : ":scalable=3Dfalse"))); return (p - name); } =20 @@ -1952,12 +1914,12 @@ else if (! asterisk) { val =3D SYMBOL_NAME (val); - p +=3D sprintf (p, "%s", SDATA (val)); + p +=3D esprintf (p, "%s", SDATA (val)); } else { val =3D SYMBOL_NAME (val); - p +=3D sprintf (p, "~%s", SDATA (val)); + p +=3D esprintf (p, "~%s", SDATA (val)); } } if (CONSP (spec)) =3D=3D=3D modified file 'src/fontset.c' --- src/fontset.c 2011-08-09 22:13:11 +0000 +++ src/fontset.c 2011-08-29 18:48:24 +0000 @@ -1700,7 +1700,7 @@ static Lisp_Object auto_fontset_alist; =20 /* Number of automatically created fontsets. */ -static int num_auto_fontsets; +static printmax_t num_auto_fontsets; =20 /* Retun a fontset synthesized from FONT-OBJECT. This is called from x_new_font when FONT-OBJECT is used for the default ASCII font of a @@ -1727,9 +1727,9 @@ alias =3D intern ("fontset-startup"); else { - char temp[32]; + char temp[sizeof "fontset-auto" + INT_STRLEN_BOUND (printmax_t)]; =20 - sprintf (temp, "fontset-auto%d", num_auto_fontsets - 1); + sprintf (temp, "fontset-auto%"pMd, num_auto_fontsets - 1); alias =3D intern (temp); } fontset_spec =3D copy_font_spec (font_spec); =3D=3D=3D modified file 'src/frame.c' --- src/frame.c 2011-08-14 06:40:45 +0000 +++ src/frame.c 2011-08-29 18:52:26 +0000 @@ -497,7 +497,7 @@ =0C /* Construct a frame that refers to a terminal. */ =20 -static int tty_frame_count; +static printmax_t tty_frame_count; =20 struct frame * make_initial_frame (void) @@ -551,7 +551,7 @@ { register struct frame *f; Lisp_Object frame; - char name[20]; + char name[sizeof "F" + INT_STRLEN_BOUND (printmax_t)]; =20 if (!terminal->name) error ("Terminal is not live, can't create new frames on it"); @@ -562,7 +562,7 @@ Vframe_list =3D Fcons (frame, Vframe_list); =20 tty_frame_count++; - sprintf (name, "F%d", tty_frame_count); + sprintf (name, "F%"pMd, tty_frame_count); f->name =3D build_string (name); =20 f->visible =3D 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */ @@ -2074,7 +2074,7 @@ /* If NAME is nil, set the name to F. */ if (NILP (name)) { - char namebuf[20]; + char namebuf[sizeof "F" + INT_STRLEN_BOUND (printmax_t)]; =20 /* Check for no change needed in this very common case before we do any consing. */ @@ -2083,7 +2083,7 @@ return; =20 tty_frame_count++; - sprintf (namebuf, "F%d", tty_frame_count); + sprintf (namebuf, "F%"pMd, tty_frame_count); name =3D build_string (namebuf); } else @@ -3065,6 +3065,7 @@ { char buf[16]; Lisp_Object tem; + unsigned long w; =20 /* Represent negative positions (off the top or left screen edge) in a way that Fmodify_frame_parameters will understand correctly. = */ @@ -3097,7 +3098,8 @@ for non-toolkit scroll bar. ruler-mode.el depends on this. */ : Qnil)); - sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f)); + w =3D FRAME_X_WINDOW (f); + sprintf (buf, "%lu", w); store_in_alist (alistptr, Qwindow_id, build_string (buf)); #ifdef HAVE_X_WINDOWS @@ -3105,7 +3107,10 @@ /* Tooltip frame may not have this widget. */ if (FRAME_X_OUTPUT (f)->widget) #endif - sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f)); + { + w =3D FRAME_OUTER_WINDOW (f); + sprintf (buf, "%lu", w); + } store_in_alist (alistptr, Qouter_window_id, build_string (buf)); #endif @@ -3576,13 +3581,13 @@ void validate_x_resource_name (void) { - int len =3D 0; + ptrdiff_t len =3D 0; /* Number of valid characters in the resource name. */ - int good_count =3D 0; + ptrdiff_t good_count =3D 0; /* Number of invalid characters in the resource name. */ - int bad_count =3D 0; + ptrdiff_t bad_count =3D 0; Lisp_Object new; - int i; + ptrdiff_t i; =20 if (!STRINGP (Vx_resource_class)) Vx_resource_class =3D build_string (EMACS_CLASS); @@ -3615,8 +3620,9 @@ if (bad_count =3D=3D 0) return; =20 - /* If name is entirely invalid, or nearly so, use `emacs'. */ - if (good_count < 2) + /* If name is entirely invalid, or nearly so, or is so implausibly + large that alloca might not work, use `emacs'. */ + if (good_count < 2 || MAX_ALLOCA - sizeof ".customization" < len) { Vx_resource_name =3D build_string ("emacs"); return; @@ -3745,20 +3751,24 @@ { char *name_key; char *class_key; + char *result; struct frame *sf =3D SELECTED_FRAME (); + ptrdiff_t invocation_namelen =3D SBYTES (Vinvocation_name); + USE_SAFE_ALLOCA; =20 /* Allocate space for the components, the dots which separate them, and the final '\0'. */ - name_key =3D (char *) alloca (SBYTES (Vinvocation_name) - + strlen (attribute) + 2); + SAFE_ALLOCA (name_key, char *, invocation_namelen + strlen (attribute)= + 2); class_key =3D (char *) alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2); =20 - sprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); + esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); sprintf (class_key, "%s.%s", EMACS_CLASS, class); =20 - return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, - name_key, class_key); + result =3D x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, + name_key, class_key); + SAFE_FREE (); + return result; } #endif =20 =3D=3D=3D modified file 'src/gtkutil.c' --- src/gtkutil.c 2011-08-05 02:19:34 +0000 +++ src/gtkutil.c 2011-08-29 20:57:42 +0000 @@ -20,6 +20,7 @@ #include =20 #ifdef USE_GTK +#include #include #include #include @@ -567,7 +568,7 @@ GtkStyleContext *gsty =3D gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f)); GdkRGBA col; - char buf[64]; + char buf[sizeof "rgbi://" + 3 * (DBL_MAX_10_EXP + sizeof "-1.000000"= - 1)]; int state =3D GTK_STATE_FLAG_SELECTED|GTK_STATE_FLAG_FOCUSED; if (get_fg) gtk_style_context_get_color (gsty, state, &col); @@ -797,7 +798,7 @@ int xneg =3D f->size_hint_flags & XNegative; int top =3D f->top_pos; int yneg =3D f->size_hint_flags & YNegative; - char geom_str[32]; + char geom_str[sizeof "=3Dx--" + 4 * INT_STRLEN_BOUND (int)]; =20 if (xneg) left =3D -left; =3D=3D=3D modified file 'src/keyboard.c' --- src/keyboard.c 2011-08-05 02:19:34 +0000 +++ src/keyboard.c 2011-08-29 15:43:34 +0000 @@ -196,7 +196,7 @@ int quit_char; =20 /* Current depth in recursive edits. */ -int command_loop_level; +EMACS_INT command_loop_level; =20 /* If not Qnil, this is a switch-frame event which we decided to put off until the end of a key sequence. This should be read as the @@ -998,7 +998,8 @@ cmd_error (Lisp_Object data) { Lisp_Object old_level, old_length; - char macroerror[50]; + char macroerror[sizeof "After..kbd macro iterations: " + + INT_STRLEN_BOUND (EMACS_INT)]; =20 #ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) @@ -1010,7 +1011,7 @@ if (executing_kbd_macro_iterations =3D=3D 1) sprintf (macroerror, "After 1 kbd macro iteration: "); else - sprintf (macroerror, "After %d kbd macro iterations: ", + sprintf (macroerror, "After %"pI"d kbd macro iterations: ", executing_kbd_macro_iterations); } else @@ -6463,11 +6464,15 @@ value =3D Fcdr_safe (Fassq (symbol_int, name_alist_or_stem)); else if (STRINGP (name_alist_or_stem)) { - int len =3D SBYTES (name_alist_or_stem); - char *buf =3D (char *) alloca (len + 50); - sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem), - XINT (symbol_int) + 1); + char *buf; + ptrdiff_t len =3D (SBYTES (name_alist_or_stem) + + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT)); + USE_SAFE_ALLOCA; + SAFE_ALLOCA (buf, char *, len); + esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem), + XINT (symbol_int) + 1); value =3D intern (buf); + SAFE_FREE (); } else if (name_table !=3D 0 && name_table[symbol_num]) value =3D intern (name_table[symbol_num]); @@ -6483,7 +6488,7 @@ =20 if (NILP (value)) { - char buf[20]; + char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)]; sprintf (buf, "key-%"pI"d", symbol_num); value =3D intern (buf); } @@ -10382,19 +10387,21 @@ char *newmessage; int message_p =3D push_message (); int count =3D SPECPDL_INDEX (); + ptrdiff_t newmessage_len, newmessage_alloc; + USE_SAFE_ALLOCA; =20 record_unwind_protect (pop_message_unwind, Qnil); binding =3D Fkey_description (bindings, Qnil); - - newmessage - =3D (char *) alloca (SCHARS (SYMBOL_NAME (function)) - + SBYTES (binding) - + 100); - sprintf (newmessage, "You can run the command `%s' with %s", - SDATA (SYMBOL_NAME (function)), - SDATA (binding)); + newmessage_alloc =3D + (sizeof "You can run the command `' with " + + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding)); + SAFE_ALLOCA (newmessage, char *, newmessage_alloc); + newmessage_len =3D + esprintf (newmessage, "You can run the command `%s' with %s", + SDATA (SYMBOL_NAME (function)), + SDATA (binding)); message2 (newmessage, - strlen (newmessage), + newmessage_len, STRING_MULTIBYTE (binding)); if (NUMBERP (Vsuggest_key_bindings)) waited =3D sit_for (Vsuggest_key_bindings, 0, 2); @@ -10404,6 +10411,7 @@ if (!NILP (waited) && message_p) restore_message (); =20 + SAFE_FREE (); unbind_to (count, Qnil); } } @@ -10633,7 +10641,9 @@ (void) { Lisp_Object temp; - XSETFASTINT (temp, command_loop_level + minibuf_level); + /* Wrap around reliably on integer overflow. */ + EMACS_INT sum =3D (command_loop_level & INTMASK) + (minibuf_level & IN= TMASK); + XSETINT (temp, sum); return temp; } =20 =3D=3D=3D modified file 'src/keymap.c' --- src/keymap.c 2011-08-14 06:40:45 +0000 +++ src/keymap.c 2011-08-29 15:43:34 +0000 @@ -2143,12 +2143,12 @@ =20 =20 char * -push_key_description (register unsigned int c, register char *p, int for= ce_multibyte) +push_key_description (EMACS_INT ch, char *p, int force_multibyte) { - unsigned c2; + int c, c2; =20 /* Clear all the meaningless bits above the meta bit. */ - c &=3D meta_modifier | ~ - meta_modifier; + c =3D ch & (meta_modifier | ~ - meta_modifier); c2 =3D c & ~(alt_modifier | ctrl_modifier | hyper_modifier | meta_modifier | shift_modifier | super_modifier); =20 @@ -2283,10 +2283,15 @@ { if (NILP (no_angles)) { - char *buffer - =3D (char *) alloca (SBYTES (SYMBOL_NAME (key)) + 5); - sprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); - return build_string (buffer); + char *buffer; + Lisp_Object result; + USE_SAFE_ALLOCA; + SAFE_ALLOCA (buffer, char *, + sizeof "<>" + SBYTES (SYMBOL_NAME (key))); + esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); + result =3D build_string (buffer); + SAFE_FREE (); + return result; } else return Fsymbol_name (key); =3D=3D=3D modified file 'src/lisp.h' --- src/lisp.h 2011-08-14 06:40:45 +0000 +++ src/lisp.h 2011-08-29 15:43:34 +0000 @@ -2895,6 +2895,16 @@ /* Defined in doprnt.c */ extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *, va_list); +extern ptrdiff_t esprintf (char *, char const *, ...) + ATTRIBUTE_FORMAT_PRINTF (2, 3); +extern ptrdiff_t esnprintf (char *, ptrdiff_t, char const *, ...) + ATTRIBUTE_FORMAT_PRINTF (3, 4); +extern ptrdiff_t exprintf (char **, ptrdiff_t *, char const *, ptrdiff_t= , + char const *, ...) + ATTRIBUTE_FORMAT_PRINTF (5, 6); +extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char const *, ptrdiff_= t, + char const *, va_list) + ATTRIBUTE_FORMAT_PRINTF (5, 0); =20 /* Defined in lread.c. */ extern Lisp_Object Qvariable_documentation, Qstandard_input; @@ -3186,7 +3196,7 @@ EXFUN (Feval_minibuffer, 2); EXFUN (Fread_string, 5); EXFUN (Fassoc_string, 3); -extern Lisp_Object get_minibuffer (int); +extern Lisp_Object get_minibuffer (EMACS_INT); extern void init_minibuf_once (void); extern void syms_of_minibuf (void); =20 @@ -3250,7 +3260,7 @@ extern void init_keyboard (void); extern void syms_of_keyboard (void); extern void keys_of_keyboard (void); -extern char *push_key_description (unsigned int, char *, int); +extern char *push_key_description (EMACS_INT, char *, int); =20 =20 /* Defined in indent.c */ =3D=3D=3D modified file 'src/lread.c' --- src/lread.c 2011-08-18 08:41:19 +0000 +++ src/lread.c 2011-08-29 18:55:58 +0000 @@ -4295,14 +4295,20 @@ void dir_warning (const char *format, Lisp_Object dirname) { - char *buffer - =3D (char *) alloca (SCHARS (dirname) + strlen (format) + 5); - fprintf (stderr, format, SDATA (dirname)); - sprintf (buffer, format, SDATA (dirname)); + /* Don't log the warning before we've initialized!! */ if (initialized) - message_dolog (buffer, strlen (buffer), 0, STRING_MULTIBYTE (dirname= )); + { + char *buffer; + ptrdiff_t message_len; + USE_SAFE_ALLOCA; + SAFE_ALLOCA (buffer, char *, + SBYTES (dirname) + strlen (format) - (sizeof "%s" - 1) + 1); + message_len =3D esprintf (buffer, format, SDATA (dirname)); + message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname))= ; + SAFE_FREE (); + } } =20 void =3D=3D=3D modified file 'src/macros.c' --- src/macros.c 2011-07-29 01:00:29 +0000 +++ src/macros.c 2011-08-29 19:07:18 +0000 @@ -35,7 +35,7 @@ This is not bound at each level, so after an error, it describes the innermost interrupted macro. */ =20 -int executing_kbd_macro_iterations; +EMACS_INT executing_kbd_macro_iterations; =20 /* This is the macro that was executing. This is not bound at each level, @@ -175,11 +175,11 @@ =20 if (XFASTINT (repeat) =3D=3D 0) Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, = loopfunc); - else + else if (XINT (repeat) > 1) { XSETINT (repeat, XINT (repeat)-1); - if (XINT (repeat) > 0) - Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loo= pfunc); + Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), + repeat, loopfunc); } return Qnil; } @@ -302,9 +302,9 @@ Lisp_Object final; Lisp_Object tem; int pdlcount =3D SPECPDL_INDEX (); - int repeat =3D 1; + EMACS_INT repeat =3D 1; struct gcpro gcpro1, gcpro2; - int success_count =3D 0; + EMACS_INT success_count =3D 0; =20 executing_kbd_macro_iterations =3D 0; =20 =3D=3D=3D modified file 'src/macros.h' --- src/macros.h 2011-01-25 04:08:28 +0000 +++ src/macros.h 2011-08-29 19:07:18 +0000 @@ -22,7 +22,7 @@ This is not bound at each level, so after an error, it describes the innermost interrupted macro. */ =20 -extern int executing_kbd_macro_iterations; +extern EMACS_INT executing_kbd_macro_iterations; =20 /* This is the macro that was executing. This is not bound at each level, @@ -42,4 +42,3 @@ /* Store a character into kbd macro being defined */ =20 extern void store_kbd_macro_char (Lisp_Object); - =3D=3D=3D modified file 'src/minibuf.c' --- src/minibuf.c 2011-08-05 02:15:35 +0000 +++ src/minibuf.c 2011-08-29 15:43:34 +0000 @@ -49,7 +49,7 @@ =20 /* Depth in minibuffer invocations. */ =20 -int minibuf_level; +EMACS_INT minibuf_level; =20 /* The maximum length of a minibuffer history. */ =20 @@ -772,10 +772,10 @@ used for nonrecursive minibuffer invocations. */ =20 Lisp_Object -get_minibuffer (int depth) +get_minibuffer (EMACS_INT depth) { Lisp_Object tail, num, buf; - char name[24]; + char name[sizeof " *Minibuf-*" + INT_STRLEN_BOUND (EMACS_INT)]; =20 XSETFASTINT (num, depth); tail =3D Fnthcdr (num, Vminibuffer_list); @@ -787,7 +787,7 @@ buf =3D Fcar (tail); if (NILP (buf) || NILP (BVAR (XBUFFER (buf), name))) { - sprintf (name, " *Minibuf-%d*", depth); + sprintf (name, " *Minibuf-%"pI"d*", depth); buf =3D Fget_buffer_create (build_string (name)); =20 /* Although the buffer's name starts with a space, undo should be =3D=3D=3D modified file 'src/nsterm.m' --- src/nsterm.m 2011-08-15 05:30:45 +0000 +++ src/nsterm.m 2011-08-29 19:09:16 +0000 @@ -5316,7 +5316,7 @@ strcpy (old_title, t); } size_title =3D xmalloc (strlen (old_title) + 40); - sprintf (size_title, "%s =E2=80=94 (%d x %d)", old_title, cols= , rows); + esprintf (size_title, "%s =E2=80=94 (%d x %d)", old_title, cols, rows= ); [window setTitle: [NSString stringWithUTF8String: size_title]]; [window display]; xfree (size_title); =3D=3D=3D modified file 'src/print.c' --- src/print.c 2011-07-28 20:23:19 +0000 +++ src/print.c 2011-08-29 19:14:47 +0000 @@ -1016,12 +1016,15 @@ { width =3D 0; do - width =3D (width * 10) + (*cp++ - '0'); + { + width =3D (width * 10) + (*cp++ - '0'); + if (DBL_DIG < width) + goto lose; + } while (*cp >=3D '0' && *cp <=3D '9'); =20 /* A precision of zero is valid only for %f. */ - if (width > DBL_DIG - || (width =3D=3D 0 && *cp !=3D 'f')) + if (width =3D=3D 0 && *cp !=3D 'f') goto lose; } =20 @@ -1314,7 +1317,9 @@ static void print_object (Lisp_Object obj, register Lisp_Object printcharfun, int es= capeflag) { - char buf[40]; + char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT= ), + max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t), + 40))]; =20 QUIT; =20 @@ -1614,8 +1619,7 @@ PRINTCHAR ('('); =20 { - EMACS_INT print_length; - int i; + printmax_t i, print_length; Lisp_Object halftail =3D obj; =20 /* Negative values of print-length are invalid in CL. @@ -1623,7 +1627,7 @@ if (NATNUMP (Vprint_length)) print_length =3D XFASTINT (Vprint_length); else - print_length =3D 0; + print_length =3D TYPE_MAXIMUM (printmax_t); =20 i =3D 0; while (CONSP (obj)) @@ -1634,7 +1638,7 @@ /* Simple but imcomplete way. */ if (i !=3D 0 && EQ (obj, halftail)) { - sprintf (buf, " . #%d", i / 2); + sprintf (buf, " . #%"pMd, i / 2); strout (buf, -1, -1, printcharfun); goto end_of_list; } @@ -1654,15 +1658,16 @@ } } =20 - if (i++) + if (i) PRINTCHAR (' '); =20 - if (print_length && i > print_length) + if (print_length <=3D i) { strout ("...", 3, 3, printcharfun); goto end_of_list; } =20 + i++; print_object (XCAR (obj), printcharfun, escapeflag); =20 obj =3D XCDR (obj); @@ -1798,19 +1803,17 @@ PRINTCHAR (' '); strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun); PRINTCHAR (' '); - sprintf (buf, "%ld/%ld", (long) h->count, - (long) ASIZE (h->next)); + sprintf (buf, "%"pI"d/%"pI"d", h->count, ASIZE (h->next)); strout (buf, -1, -1, printcharfun); } - sprintf (buf, " 0x%lx", (unsigned long) h); + sprintf (buf, " %p", h); strout (buf, -1, -1, printcharfun); PRINTCHAR ('>'); #endif /* Implement a readable output, e.g.: #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ /* Always print the size. */ - sprintf (buf, "#s(hash-table size %ld", - (long) ASIZE (h->next)); + sprintf (buf, "#s(hash-table size %"pI"d", ASIZE (h->next)); strout (buf, -1, -1, printcharfun); =20 if (!NILP (h->test)) @@ -2038,7 +2041,7 @@ if (MISCP (obj)) sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj)); else if (VECTORLIKEP (obj)) - sprintf (buf, "(PVEC 0x%08lx)", (unsigned long) ASIZE (obj)); + sprintf (buf, "(PVEC 0x%08"pI"x)", ASIZE (obj)); else sprintf (buf, "(0x%02x)", (int) XTYPE (obj)); strout (buf, -1, -1, printcharfun); =3D=3D=3D modified file 'src/process.c' --- src/process.c 2011-08-24 21:20:36 +0000 +++ src/process.c 2011-08-29 19:46:15 +0000 @@ -616,8 +616,8 @@ { register Lisp_Object val, tem, name1; register struct Lisp_Process *p; - char suffix[10]; - register int i; + char suffix[sizeof "<>" + INT_STRLEN_BOUND (printmax_t)]; + printmax_t i; =20 p =3D allocate_process (); =20 @@ -651,7 +651,7 @@ { tem =3D Fget_process (name1); if (NILP (tem)) break; - sprintf (suffix, "<%d>", i); + sprintf (suffix, "<%"pMd">", i); name1 =3D concat2 (name, build_string (suffix)); } name =3D name1; =3D=3D=3D modified file 'src/term.c' --- src/term.c 2011-08-30 17:32:44 +0000 +++ src/term.c 2011-08-30 21:16:49 +0000 @@ -1817,7 +1817,7 @@ { int face_id; int len; - char buf[9]; + char buf[sizeof "\\x" + max (6, (sizeof it->c * CHAR_BIT + 3) / 4)]; char const *str =3D " "; =20 /* Get a face ID for the glyph by utilizing a cache (the same way as =3D=3D=3D modified file 'src/window.h' --- src/window.h 2011-07-02 10:36:48 +0000 +++ src/window.h 2011-08-29 15:43:34 +0000 @@ -847,11 +847,11 @@ =20 /* Depth in recursive edits. */ =20 -extern int command_loop_level; +extern EMACS_INT command_loop_level; =20 /* Depth in minibuffer invocations. */ =20 -extern int minibuf_level; +extern EMACS_INT minibuf_level; =20 /* true if we should redraw the mode lines on the next redisplay. */ =20 =3D=3D=3D modified file 'src/xfaces.c' --- src/xfaces.c 2011-08-19 14:28:36 +0000 +++ src/xfaces.c 2011-08-29 19:58:56 +0000 @@ -3549,6 +3549,8 @@ rdb !=3D NULL)) { char line[512]; + char *buf =3D line; + ptrdiff_t bufsize =3D sizeof line; Lisp_Object lface =3D lface_from_face_name (f, Qmenu, 1); struct face *face =3D FACE_FROM_ID (f, MENU_FACE_ID); const char *myname =3D SSDATA (Vx_resource_name); @@ -3561,24 +3563,25 @@ =20 if (STRINGP (LFACE_FOREGROUND (lface))) { - sprintf (line, "%s.%s*foreground: %s", - myname, popup_path, - SDATA (LFACE_FOREGROUND (lface))); + exprintf (&buf, &bufsize, line, -1, "%s.%s*foreground: %s", + myname, popup_path, + SDATA (LFACE_FOREGROUND (lface))); XrmPutLineResource (&rdb, line); - sprintf (line, "%s.pane.menubar*foreground: %s", - myname, SDATA (LFACE_FOREGROUND (lface))); + exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*foreground: %s", + myname, SDATA (LFACE_FOREGROUND (lface))); XrmPutLineResource (&rdb, line); changed_p =3D 1; } =20 if (STRINGP (LFACE_BACKGROUND (lface))) { - sprintf (line, "%s.%s*background: %s", - myname, popup_path, - SDATA (LFACE_BACKGROUND (lface))); + exprintf (&buf, &bufsize, line, -1, "%s.%s*background: %s", + myname, popup_path, + SDATA (LFACE_BACKGROUND (lface))); XrmPutLineResource (&rdb, line); - sprintf (line, "%s.pane.menubar*background: %s", - myname, SDATA (LFACE_BACKGROUND (lface))); + + exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*background: %s", + myname, SDATA (LFACE_BACKGROUND (lface))); XrmPutLineResource (&rdb, line); changed_p =3D 1; } @@ -3616,11 +3619,12 @@ #else char *fontsetname =3D SSDATA (xlfd); #endif - sprintf (line, "%s.pane.menubar*font%s: %s", - myname, suffix, fontsetname); + exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*font%s: %s", + myname, suffix, fontsetname); XrmPutLineResource (&rdb, line); - sprintf (line, "%s.%s*font%s: %s", - myname, popup_path, suffix, fontsetname); + + exprintf (&buf, &bufsize, line, -1, "%s.%s*font%s: %s", + myname, popup_path, suffix, fontsetname); XrmPutLineResource (&rdb, line); changed_p =3D 1; if (fontsetname !=3D SSDATA (xlfd)) @@ -3630,6 +3634,9 @@ =20 if (changed_p && f->output_data.x->menubar_widget) free_frame_menubar (f); + + if (buf !=3D line) + xfree (buf); } } =20 =3D=3D=3D modified file 'src/xfns.c' --- src/xfns.c 2011-08-05 02:15:35 +0000 +++ src/xfns.c 2011-08-29 19:59:51 +0000 @@ -2440,7 +2440,7 @@ /* Do some needed geometry management. */ { ptrdiff_t len; - char *tem, shell_position[32]; + char *tem, shell_position[sizeof "=3Dx++" + 4 * INT_STRLEN_BOUND (in= t)]; Arg gal[10]; int gac =3D 0; int extra_borders =3D 0; =3D=3D=3D modified file 'src/xterm.c' --- src/xterm.c 2011-08-05 02:19:34 +0000 +++ src/xterm.c 2011-08-29 20:03:30 +0000 @@ -7900,7 +7900,8 @@ { char buf[256]; =20 - sprintf (buf, "Connection lost to X server `%s'", DisplayString (displ= ay)); + snprintf (buf, sizeof buf, "Connection lost to X server `%s'", + DisplayString (display)); x_connection_closed (display, buf); return 0; } =3D=3D=3D modified file 'src/xterm.h' --- src/xterm.h 2011-07-07 02:24:56 +0000 +++ src/xterm.h 2011-08-29 20:04:46 +0000 @@ -955,7 +955,8 @@ extern int x_text_icon (struct frame *, const char *); extern int x_bitmap_icon (struct frame *, Lisp_Object); extern void x_catch_errors (Display *); -extern void x_check_errors (Display *, const char *); +extern void x_check_errors (Display *, const char *) + ATTRIBUTE_FORMAT_PRINTF (2, 0); extern int x_had_errors_p (Display *); extern int x_catching_errors (void); extern void x_uncatch_errors (void);