sprintf-related integer and memory overflow issues

Fixes: debbugs:9397 debbugs:9412
This commit is contained in:
Paul Eggert 2011-09-04 14:52:59 -07:00
commit 86633eab8a
38 changed files with 801 additions and 409 deletions

View file

@ -1,3 +1,7 @@
2011-09-04 Paul Eggert <eggert@cs.ucla.edu>
* configure.in (snprintf): New check.
2011-08-30 Paul Eggert <eggert@cs.ucla.edu>
* configure.in (opsys): Change pattern to *-*-linux*

View file

@ -3071,6 +3071,8 @@ fi
AC_FUNC_FORK
AC_CHECK_FUNCS(snprintf)
dnl Adapted from Haible's version.
AC_CACHE_CHECK([for nl_langinfo and CODESET], emacs_cv_langinfo_codeset,
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <langinfo.h>]],

View file

@ -1,3 +1,38 @@
2011-09-04 Paul Eggert <eggert@cs.ucla.edu>
Integer and memory overflow issues (Bug#9397).
* emacsclient.c (xmalloc): Accept size_t, not unsigned int, to
avoid potential buffer overflow issues on typical 64-bit hosts.
Return void *, not long *.
(get_current_dir_name): Report a failure, instead of looping
forever, if buffer size calculation overflows. Treat malloc
failures like realloc failures, as that has better behavior and is
more consistent. Do not check whether xmalloc returns NULL, as
that's not possible.
(message): Do not arbitrarily truncate message to 2048 bytes when
sending it to stderr; use vfprintf instead.
(get_server_config, set_local_socket)
(start_daemon_and_retry_set_socket): Do not alloca
arbitrarily-large buffers; that's not safe.
(get_server_config, set_local_socket): Do not use sprintf when its
result might not fit in 'int'.
(set_local_socket): Do not assume uid fits in 'int'.
* etags.c (xmalloc, xrealloc): Accept size_t, not unsigned int,
to avoid potential buffer overflow issues on typical 64-bit hosts.
(whatlen_max): New static var.
(main): Avoid buffer overflow if subsidiary command length is
greater than BUFSIZ or 2*BUFSIZ + 20. Do not use sprintf when its
result might not fit in 'int'.
* movemail.c (main): Do not use sprintf when its result might not fit
in 'int'. Instead, put the possibly-long file name into the
output of pfatal_with_name.
* update-game-score.c: Include <limits.h>
(get_user_id): Do not assume uid fits in 'int'. Simplify.
2011-07-28 Paul Eggert <eggert@cs.ucla.edu>
Assume freestanding C89 headers, string.h, stdlib.h.

View file

@ -194,10 +194,10 @@ struct option longopts[] =
/* Like malloc but get fatal error if memory is exhausted. */
static long *
xmalloc (unsigned int size)
static void *
xmalloc (size_t size)
{
long *result = (long *) malloc (size);
void *result = malloc (size);
if (result == NULL)
{
perror ("malloc");
@ -250,32 +250,33 @@ get_current_dir_name (void)
)
{
buf = (char *) xmalloc (strlen (pwd) + 1);
if (!buf)
return NULL;
strcpy (buf, pwd);
}
#ifdef HAVE_GETCWD
else
{
size_t buf_size = 1024;
buf = (char *) xmalloc (buf_size);
if (!buf)
return NULL;
for (;;)
{
int tmp_errno;
buf = malloc (buf_size);
if (! buf)
break;
if (getcwd (buf, buf_size) == buf)
break;
if (errno != ERANGE)
tmp_errno = errno;
free (buf);
if (tmp_errno != ERANGE)
{
int tmp_errno = errno;
free (buf);
errno = tmp_errno;
return NULL;
}
buf_size *= 2;
buf = (char *) realloc (buf, buf_size);
if (!buf)
return NULL;
if (! buf_size)
{
errno = ENOMEM;
return NULL;
}
}
}
#else
@ -283,8 +284,6 @@ get_current_dir_name (void)
{
/* We need MAXPATHLEN here. */
buf = (char *) xmalloc (MAXPATHLEN + 1);
if (!buf)
return NULL;
if (getwd (buf) == NULL)
{
int tmp_errno = errno;
@ -494,16 +493,17 @@ static void message (int, const char *, ...) ATTRIBUTE_FORMAT_PRINTF (2, 3);
static void
message (int is_error, const char *format, ...)
{
char msg[2048];
va_list args;
va_start (args, format);
vsprintf (msg, format, args);
va_end (args);
#ifdef WINDOWSNT
if (w32_window_app ())
{
char msg[2048];
vsnprintf (msg, sizeof msg, format, args);
msg[sizeof msg - 1] = '\0';
if (is_error)
MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
else
@ -514,9 +514,11 @@ message (int is_error, const char *format, ...)
{
FILE *f = is_error ? stderr : stdout;
fputs (msg, f);
vfprintf (f, format, args);
fflush (f);
}
va_end (args);
}
/* Decode the options from argv and argc.
@ -959,18 +961,24 @@ get_server_config (struct sockaddr_in *server, char *authentication)
if (home)
{
char *path = alloca (strlen (home) + strlen (server_file)
+ EXTRA_SPACE);
sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
char *path = xmalloc (strlen (home) + strlen (server_file)
+ EXTRA_SPACE);
strcpy (path, home);
strcat (path, "/.emacs.d/server/");
strcat (path, server_file);
config = fopen (path, "rb");
free (path);
}
#ifdef WINDOWSNT
if (!config && (home = egetenv ("APPDATA")))
{
char *path = alloca (strlen (home) + strlen (server_file)
+ EXTRA_SPACE);
sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
char *path = xmalloc (strlen (home) + strlen (server_file)
+ EXTRA_SPACE);
strcpy (path, home);
strcat (path, "/.emacs.d/server/");
strcat (path, server_file);
config = fopen (path, "rb");
free (path);
}
#endif
}
@ -1243,6 +1251,8 @@ set_local_socket (void)
int saved_errno = 0;
const char *server_name = "server";
const char *tmpdir IF_LINT ( = NULL);
char *tmpdir_storage = NULL;
char *socket_name_storage = NULL;
if (socket_name && !strchr (socket_name, '/')
&& !strchr (socket_name, '\\'))
@ -1255,6 +1265,8 @@ set_local_socket (void)
if (default_sock)
{
long uid = geteuid ();
ptrdiff_t tmpdirlen;
tmpdir = egetenv ("TMPDIR");
if (!tmpdir)
{
@ -1265,17 +1277,19 @@ set_local_socket (void)
size_t n = confstr (_CS_DARWIN_USER_TEMP_DIR, NULL, (size_t) 0);
if (n > 0)
{
tmpdir = alloca (n);
tmpdir = tmpdir_storage = xmalloc (n);
confstr (_CS_DARWIN_USER_TEMP_DIR, tmpdir, n);
}
else
#endif
tmpdir = "/tmp";
}
socket_name = alloca (strlen (tmpdir) + strlen (server_name)
+ EXTRA_SPACE);
sprintf (socket_name, "%s/emacs%d/%s",
tmpdir, (int) geteuid (), server_name);
tmpdirlen = strlen (tmpdir);
socket_name = socket_name_storage =
xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE);
strcpy (socket_name, tmpdir);
sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid);
strcat (socket_name + tmpdirlen, server_name);
}
if (strlen (socket_name) < sizeof (server.sun_path))
@ -1309,10 +1323,13 @@ set_local_socket (void)
if (pw && (pw->pw_uid != geteuid ()))
{
/* We're running under su, apparently. */
socket_name = alloca (strlen (tmpdir) + strlen (server_name)
+ EXTRA_SPACE);
sprintf (socket_name, "%s/emacs%d/%s",
tmpdir, (int) pw->pw_uid, server_name);
long uid = pw->pw_uid;
ptrdiff_t tmpdirlen = strlen (tmpdir);
socket_name = xmalloc (tmpdirlen + strlen (server_name)
+ EXTRA_SPACE);
strcpy (socket_name, tmpdir);
sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid);
strcat (socket_name + tmpdirlen, server_name);
if (strlen (socket_name) < sizeof (server.sun_path))
strcpy (server.sun_path, socket_name);
@ -1322,6 +1339,7 @@ set_local_socket (void)
progname, socket_name);
exit (EXIT_FAILURE);
}
free (socket_name);
sock_status = socket_status (server.sun_path);
saved_errno = errno;
@ -1331,6 +1349,9 @@ set_local_socket (void)
}
}
free (socket_name_storage);
free (tmpdir_storage);
switch (sock_status)
{
case 1:
@ -1526,8 +1547,8 @@ start_daemon_and_retry_set_socket (void)
{
/* Pass --daemon=socket_name as argument. */
const char *deq = "--daemon=";
char *daemon_arg = alloca (strlen (deq)
+ strlen (socket_name) + 1);
char *daemon_arg = xmalloc (strlen (deq)
+ strlen (socket_name) + 1);
strcpy (daemon_arg, deq);
strcat (daemon_arg, socket_name);
d_argv[1] = daemon_arg;

View file

@ -414,8 +414,8 @@ static bool filename_is_absolute (char *f);
static void canonicalize_filename (char *);
static void linebuffer_init (linebuffer *);
static void linebuffer_setlen (linebuffer *, int);
static PTR xmalloc (unsigned int);
static PTR xrealloc (char *, unsigned int);
static PTR xmalloc (size_t);
static PTR xrealloc (char *, size_t);
static char searchar = '/'; /* use /.../ searches */
@ -425,6 +425,7 @@ static char *progname; /* name this program was invoked with */
static char *cwd; /* current working directory */
static char *tagfiledir; /* directory of tagfile */
static FILE *tagf; /* ioptr for tags file */
static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */
static fdesc *fdhead; /* head of file description list */
static fdesc *curfdp; /* current file description */
@ -1066,6 +1067,7 @@ main (int argc, char **argv)
int current_arg, file_count;
linebuffer filename_lb;
bool help_asked = FALSE;
ptrdiff_t len;
char *optstring;
int opt;
@ -1110,6 +1112,9 @@ main (int argc, char **argv)
/* This means that a file name has been seen. Record it. */
argbuffer[current_arg].arg_type = at_filename;
argbuffer[current_arg].what = optarg;
len = strlen (optarg);
if (whatlen_max < len)
whatlen_max = len;
++current_arg;
++file_count;
break;
@ -1118,6 +1123,9 @@ main (int argc, char **argv)
/* Parse standard input. Idea by Vivek <vivek@etla.org>. */
argbuffer[current_arg].arg_type = at_stdin;
argbuffer[current_arg].what = optarg;
len = strlen (optarg);
if (whatlen_max < len)
whatlen_max = len;
++current_arg;
++file_count;
if (parsing_stdin)
@ -1160,6 +1168,9 @@ main (int argc, char **argv)
case 'r':
argbuffer[current_arg].arg_type = at_regexp;
argbuffer[current_arg].what = optarg;
len = strlen (optarg);
if (whatlen_max < len)
whatlen_max = len;
++current_arg;
break;
case 'R':
@ -1198,6 +1209,9 @@ main (int argc, char **argv)
{
argbuffer[current_arg].arg_type = at_filename;
argbuffer[current_arg].what = argv[optind];
len = strlen (argv[optind]);
if (whatlen_max < len)
whatlen_max = len;
++current_arg;
++file_count;
}
@ -1331,7 +1345,9 @@ main (int argc, char **argv)
/* From here on, we are in (CTAGS && !cxref_style) */
if (update)
{
char cmd[BUFSIZ];
char *cmd =
xmalloc (strlen (tagfile) + whatlen_max +
sizeof "mv..OTAGS;fgrep -v '\t\t' OTAGS >;rm OTAGS");
for (i = 0; i < current_arg; ++i)
{
switch (argbuffer[i].arg_type)
@ -1342,12 +1358,17 @@ main (int argc, char **argv)
default:
continue; /* the for loop */
}
sprintf (cmd,
"mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
tagfile, argbuffer[i].what, tagfile);
strcpy (cmd, "mv ");
strcat (cmd, tagfile);
strcat (cmd, " OTAGS;fgrep -v '\t");
strcat (cmd, argbuffer[i].what);
strcat (cmd, "\t' OTAGS >");
strcat (cmd, tagfile);
strcat (cmd, ";rm OTAGS");
if (system (cmd) != EXIT_SUCCESS)
fatal ("failed to execute shell command", (char *)NULL);
}
free (cmd);
append_to_tagfile = TRUE;
}
@ -1363,11 +1384,14 @@ main (int argc, char **argv)
if (CTAGS)
if (append_to_tagfile || update)
{
char cmd[2*BUFSIZ+20];
char *cmd = xmalloc (2 * strlen (tagfile) + sizeof "sort -u -o..");
/* Maybe these should be used:
setenv ("LC_COLLATE", "C", 1);
setenv ("LC_ALL", "C", 1); */
sprintf (cmd, "sort -u -o %.*s %.*s", BUFSIZ, tagfile, BUFSIZ, tagfile);
strcpy (cmd, "sort -u -o ");
strcat (cmd, tagfile);
strcat (cmd, " ");
strcat (cmd, tagfile);
exit (system (cmd));
}
return EXIT_SUCCESS;
@ -6656,7 +6680,7 @@ linebuffer_setlen (linebuffer *lbp, int toksize)
/* Like malloc but get fatal error if memory is exhausted. */
static PTR
xmalloc (unsigned int size)
xmalloc (size_t size)
{
PTR result = (PTR) malloc (size);
if (result == NULL)
@ -6665,7 +6689,7 @@ xmalloc (unsigned int size)
}
static PTR
xrealloc (char *ptr, unsigned int size)
xrealloc (char *ptr, size_t size)
{
PTR result = (PTR) realloc (ptr, size);
if (result == NULL)

View file

@ -325,11 +325,10 @@ main (int argc, char **argv)
if (desc < 0)
{
int mkstemp_errno = errno;
char *message = (char *) xmalloc (strlen (tempname) + 50);
sprintf (message, "creating %s, which would become the lock file",
tempname);
error ("error while creating what would become the lock file",
0, 0);
errno = mkstemp_errno;
pfatal_with_name (message);
pfatal_with_name (tempname);
}
close (desc);

View file

@ -35,6 +35,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@ -128,19 +129,13 @@ lose_syserr (const char *msg)
static char *
get_user_id (void)
{
char *name;
struct passwd *buf = getpwuid (getuid ());
if (!buf)
{
int count = 1;
int uid = (int) getuid ();
int tuid = uid;
while (tuid /= 10)
count++;
name = malloc (count+1);
if (!name)
return NULL;
sprintf (name, "%d", uid);
long uid = getuid ();
char *name = malloc (sizeof uid * CHAR_BIT / 3 + 1);
if (name)
sprintf (name, "%ld", uid);
return name;
}
return buf->pw_name;

View file

@ -1,3 +1,7 @@
2011-09-04 Paul Eggert <eggert@cs.ucla.edu>
* config.nt (HAVE_SNPRINTF): New macro.
2011-07-28 Paul Eggert <eggert@cs.ucla.edu>
Assume freestanding C89 headers, string.h, stdlib.h.

View file

@ -240,6 +240,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define HAVE_SETSOCKOPT 1
#define HAVE_GETSOCKNAME 1
#define HAVE_GETPEERNAME 1
#define HAVE_SNPRINTF 1
#define HAVE_LANGINFO_CODESET 1
/* Local (unix) sockets are not supported. */
#undef HAVE_SYS_UN_H

View file

@ -1,15 +1,121 @@
2011-09-04 Paul Eggert <eggert@cs.ucla.edu>
sprintf-related integer and memory overflow issues (Bug#9412).
* doprnt.c (doprnt): Support printing ptrdiff_t and intmax_t values.
(esprintf, 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, 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 == 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 <float.h>, 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.
(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 <float.h>, 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.
* sysdep.c (snprintf) [! HAVE_SNPRINTF]: New function.
* 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-09-04 Paul Eggert <eggert@cs.ucla.edu>
Integer overflow fixes for scrolling, etc.
Without this fix, Emacs silently mishandles large integers sometimes.
For example, "C-u 4294967297 M-x recenter" was be treated as if
Without these, Emacs silently mishandles large integers sometimes.
For example, "C-u 4294967297 M-x recenter" was treated as if
it were "C-u 1 M-x recenter" on a typical 64-bit host.
* xdisp.c: Integer overflow fix.
(try_window_id): Check Emacs fixnum range before converting to 'int'.
* xdisp.c (try_window_id): Check Emacs fixnum range before
converting to 'int'.
* window.c: Integer overflow fixes.
(window_scroll_line_based, Frecenter):
* window.c (window_scroll_line_based, Frecenter):
Check that an Emacs fixnum is in range before assigning it to 'int'.
(Frecenter, Fmove_to_window_line): Use EMACS_INT, not int, for
values converted from Emacs fixnums.
@ -18,18 +124,15 @@
(Fset_window_configuration, compare_window_configurations):
Use ptrdiff_t, not int, for index that might exceed 2 GiB.
* search.c: Integer overflow fixes
(Freplace_match): Use ptrdiff_t, not int, for indexes that can
exceed INT_MAX. Check that EMACS_INT value is in range before
assigning it to the (possibly-narrower) index.
* search.c (Freplace_match): Use ptrdiff_t, not int, for indexes
that can exceed INT_MAX. Check that EMACS_INT value is in range
before assigning it to the (possibly-narrower) index.
(match_limit): Don't assume that a fixnum can fit in 'int'.
* print.c: Integer overflow fix.
(print_object): Use ptrdiff_t, not int, for index that can
* print.c (print_object): Use ptrdiff_t, not int, for index that can
exceed INT_MAX.
* indent.c: Integer overflow fixes.
(position_indentation): Now takes ptrdiff_t, not int.
* indent.c (position_indentation): Now takes ptrdiff_t, not int.
(Fvertical_motion): Don't wrap around LINES values that don't fit
in 'int'. Instead, treat them as extreme values. This is good
enough for windows, which can't have more than INT_MAX lines anyway.

View file

@ -259,6 +259,18 @@ xd_symbol_to_dbus_type (Lisp_Object object)
} \
while (0)
/* 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 = strlen (signature);
ptrdiff_t xlen = strlen (x);
if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <= 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,8 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
{
unsigned int subtype;
Lisp_Object elt;
char const *subsig;
int subsiglen;
char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
elt = object;
@ -328,12 +342,13 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
if (NILP (elt))
{
subtype = DBUS_TYPE_STRING;
strcpy (x, DBUS_TYPE_STRING_AS_STRING);
subsig = DBUS_TYPE_STRING_AS_STRING;
}
else
{
subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
subsig = x;
}
/* If the element type is DBUS_TYPE_SIGNATURE, and this is the
@ -342,7 +357,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
if ((subtype == 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 = SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt)));
while (!NILP (elt))
{
@ -351,7 +366,10 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
elt = CDR_SAFE (XD_NEXT_VALUE (elt));
}
sprintf (signature, "%c%s", dtype, x);
subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
"%c%s", dtype, subsig);
if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH))
string_overflow ();
break;
case DBUS_TYPE_VARIANT:
@ -383,10 +401,10 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
{
subtype = 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 = CDR_SAFE (XD_NEXT_VALUE (elt));
}
strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
break;
case DBUS_TYPE_DICT_ENTRY:
@ -407,7 +425,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
elt = XD_NEXT_VALUE (elt);
subtype = 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);
if (!XD_BASIC_DBUS_TYPE (subtype))
wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
@ -416,14 +434,14 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
elt = CDR_SAFE (XD_NEXT_VALUE (elt));
subtype = 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);
if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
wrong_type_argument (intern ("D-Bus"),
CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
/* Closing signature. */
strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
break;
default:
@ -2026,7 +2044,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
DBusConnection *connection;
ptrdiff_t i;
char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
int rulelen;
DBusError derror;
/* Check parameters. */
@ -2071,32 +2089,43 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
connection = xd_initialize (bus, TRUE);
/* Create a rule to receive related signals. */
sprintf (rule,
"type='signal',interface='%s',member='%s'",
SDATA (interface),
SDATA (signal));
rulelen = snprintf (rule, sizeof rule,
"type='signal',interface='%s',member='%s'",
SDATA (interface),
SDATA (signal));
if (! (0 <= rulelen && rulelen < sizeof rule))
string_overflow ();
/* Add unique name and path to the rule if they are non-nil. */
if (!NILP (uname))
{
sprintf (x, ",sender='%s'", SDATA (uname));
strcat (rule, x);
int len = snprintf (rule + rulelen, sizeof rule - rulelen,
",sender='%s'", SDATA (uname));
if (! (0 <= len && len < sizeof rule - rulelen))
string_overflow ();
rulelen += len;
}
if (!NILP (path))
{
sprintf (x, ",path='%s'", SDATA (path));
strcat (rule, x);
int len = snprintf (rule + rulelen, sizeof rule - rulelen,
",path='%s'", SDATA (path));
if (! (0 <= len && len < sizeof rule - rulelen))
string_overflow ();
rulelen += len;
}
/* Add arguments to the rule if they are non-nil. */
for (i = 6; i < nargs; ++i)
if (!NILP (args[i]))
{
int len;
CHECK_STRING (args[i]);
sprintf (x, ",arg%"pD"d='%s'", i - 6,
SDATA (args[i]));
strcat (rule, x);
len = snprintf (rule + rulelen, sizeof rule - rulelen,
",arg%"pD"d='%s'", i - 6, SDATA (args[i]));
if (! (0 <= len && len < sizeof rule - rulelen))
string_overflow ();
rulelen += len;
}
/* Add the rule to the bus. */

View file

@ -272,15 +272,16 @@ add_window_display_history (struct window *w, const char *msg, int paused_p)
buf = redisplay_history[history_idx].trace;
++history_idx;
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);
snprintf (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);
}

View file

@ -70,9 +70,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
%<flags><width><precision><length>character
where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length
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.
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 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
modifier: it is supported for %d, %o, and %x conversions of integral
arguments, must immediately precede the conversion specifier, and means that
the respective argument is to be treated as `long int' or `unsigned long
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'.
The width specifier supplies a lower limit for the length of the printed
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,
{
ptrdiff_t size_bound = 0;
EMACS_INT width; /* Columns occupied by STRING on display. */
int long_flag = 0;
int pIlen = sizeof pI - 1;
enum {
pDlen = sizeof pD - 1,
pIlen = sizeof pI - 1,
pMlen = sizeof pMd - 2
};
enum {
no_modifier, long_modifier, pD_modifier, pI_modifier, pM_modifier
} length_modifier = no_modifier;
static char const modifier_len[] = { 0, 1, pDlen, pIlen, pMlen };
int maxmlen = max (max (1, pDlen), max (pIlen, pMlen));
int mlen;
fmt++;
/* Copy this one %-spec into fmtcpy. */
@ -213,19 +224,26 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
fmt++;
}
if (0 < pIlen && pIlen <= format_end - fmt
&& memcmp (fmt, pI, pIlen) == 0)
/* Check for the length modifiers in textual length order, so
that longer modifiers override shorter ones. */
for (mlen = 1; mlen <= maxmlen; mlen++)
{
long_flag = 2;
memcpy (string, fmt + 1, pIlen);
string += pIlen;
fmt += pIlen;
}
else if (fmt < format_end && *fmt == 'l')
{
long_flag = 1;
*string++ = *++fmt;
if (format_end - fmt < mlen)
break;
if (mlen == 1 && *fmt == 'l')
length_modifier = long_modifier;
if (mlen == pDlen && memcmp (fmt, pD, pDlen) == 0)
length_modifier = pD_modifier;
if (mlen == pIlen && memcmp (fmt, pI, pIlen) == 0)
length_modifier = pI_modifier;
if (mlen == pMlen && memcmp (fmt, pMd, pMlen) == 0)
length_modifier = pM_modifier;
}
mlen = modifier_len[length_modifier];
memcpy (string, fmt + 1, mlen);
string += mlen;
fmt += mlen;
*string = 0;
/* Make the size bound large enough to handle floating point formats
@ -252,55 +270,78 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
/* case 'b': */
case 'l':
case 'd':
{
int i;
long l;
if (1 < long_flag)
switch (length_modifier)
{
case no_modifier:
{
EMACS_INT ll = va_arg (ap, EMACS_INT);
sprintf (sprintf_buffer, fmtcpy, ll);
int v = va_arg (ap, int);
sprintf (sprintf_buffer, fmtcpy, v);
}
else if (long_flag)
break;
case long_modifier:
{
l = va_arg(ap, long);
sprintf (sprintf_buffer, fmtcpy, l);
long v = va_arg (ap, long);
sprintf (sprintf_buffer, fmtcpy, v);
}
else
break;
case pD_modifier:
signed_pD_modifier:
{
i = va_arg(ap, int);
sprintf (sprintf_buffer, fmtcpy, i);
ptrdiff_t v = va_arg (ap, ptrdiff_t);
sprintf (sprintf_buffer, fmtcpy, v);
}
/* Now copy into final output, truncating as necessary. */
string = sprintf_buffer;
goto doit;
}
break;
case pI_modifier:
{
EMACS_INT v = va_arg (ap, EMACS_INT);
sprintf (sprintf_buffer, fmtcpy, v);
}
break;
case pM_modifier:
{
intmax_t v = va_arg (ap, intmax_t);
sprintf (sprintf_buffer, fmtcpy, v);
}
break;
}
/* Now copy into final output, truncating as necessary. */
string = sprintf_buffer;
goto doit;
case 'o':
case 'x':
{
unsigned u;
unsigned long ul;
if (1 < long_flag)
switch (length_modifier)
{
case no_modifier:
{
EMACS_UINT ull = va_arg (ap, EMACS_UINT);
sprintf (sprintf_buffer, fmtcpy, ull);
unsigned v = va_arg (ap, unsigned);
sprintf (sprintf_buffer, fmtcpy, v);
}
else if (long_flag)
break;
case long_modifier:
{
ul = va_arg(ap, unsigned long);
sprintf (sprintf_buffer, fmtcpy, ul);
unsigned long v = va_arg (ap, unsigned long);
sprintf (sprintf_buffer, fmtcpy, v);
}
else
break;
case pD_modifier:
goto signed_pD_modifier;
case pI_modifier:
{
u = va_arg(ap, unsigned);
sprintf (sprintf_buffer, fmtcpy, u);
EMACS_UINT v = va_arg (ap, EMACS_UINT);
sprintf (sprintf_buffer, fmtcpy, v);
}
/* Now copy into final output, truncating as necessary. */
string = sprintf_buffer;
goto doit;
}
break;
case pM_modifier:
{
uintmax_t v = va_arg (ap, uintmax_t);
sprintf (sprintf_buffer, fmtcpy, v);
}
break;
}
/* Now copy into final output, truncating as necessary. */
string = sprintf_buffer;
goto doit;
case 'f':
case 'e':
@ -426,3 +467,61 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
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 = doprnt (buf, TYPE_MAXIMUM (ptrdiff_t), 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 = evxprintf (buf, bufsize, nonheapbuf, bufsize_max, format, ap);
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 = doprnt (*buf, *bufsize, format, 0, ap_copy);
va_end (ap_copy);
if (nbytes < *bufsize - 1)
return nbytes;
if (*buf != nonheapbuf)
xfree (*buf);
*buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1);
}
}

View file

@ -2014,7 +2014,7 @@ the data it can't find. */)
{
int offset = tm_diff (t, &gmt);
char *s = 0;
char buf[6];
char buf[sizeof "+00" + INT_STRLEN_BOUND (int)];
#ifdef HAVE_TM_ZONE
if (t->tm_zone)
@ -2029,7 +2029,8 @@ the data it can't find. */)
if (!s)
{
/* No local time zone name is available; use "+-NNNN" instead. */
int am = (offset < 0 ? -offset : offset) / 60;
int m = offset / 60;
int am = offset < 0 ? - m : m;
sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
s = buf;
}

View file

@ -1072,15 +1072,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
if (!dname_arg || !strchr (dname_arg, '\n'))
{ /* In orig, child: now exec w/special daemon name. */
char fdStr[80];
int fdStrlen =
snprintf (fdStr, sizeof fdStr,
"--daemon=\n%d,%d\n%s", daemon_pipe[0],
daemon_pipe[1], dname_arg ? dname_arg : "");
if (dname_arg && strlen (dname_arg) > 70)
if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr))
{
fprintf (stderr, "daemon: child name too long\n");
exit (1);
}
sprintf (fdStr, "--daemon=\n%d,%d\n%s", daemon_pipe[0],
daemon_pipe[1], dname_arg ? dname_arg : "");
argv[skip_args] = fdStr;
execv (argv[0], argv);

View file

@ -1951,35 +1951,11 @@ verror (const char *m, va_list ap)
char buf[4000];
ptrdiff_t size = sizeof buf;
ptrdiff_t size_max = STRING_BYTES_BOUND + 1;
char const *m_end = m + strlen (m);
char *buffer = buf;
ptrdiff_t used;
Lisp_Object string;
while (1)
{
va_list ap_copy;
va_copy (ap_copy, ap);
used = doprnt (buffer, size, m, m_end, ap_copy);
va_end (ap_copy);
/* 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 <= size_max / 2)
size *= 2;
else if (size < size_max)
size = size_max;
else
break; /* and leave the message truncated */
if (buffer != buf)
xfree (buffer);
buffer = (char *) xmalloc (size);
}
used = evxprintf (&buffer, &size, buf, size_max, m, ap);
string = make_string (buffer, used);
if (buffer != buf)
xfree (buffer);

View file

@ -341,6 +341,9 @@ lock_file_1 (char *lfname, int force)
const char *user_name;
const char *host_name;
char *lock_info_str;
ptrdiff_t lock_info_size;
int symlink_errno;
USE_SAFE_ALLOCA;
/* Call this first because it can GC. */
boot = get_boot_time ();
@ -353,17 +356,14 @@ lock_file_1 (char *lfname, int force)
host_name = SSDATA (Fsystem_name ());
else
host_name = "";
lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
+ 2 * INT_STRLEN_BOUND (printmax_t)
+ sizeof "@.:");
lock_info_size = (strlen (user_name) + strlen (host_name)
+ 2 * INT_STRLEN_BOUND (printmax_t)
+ sizeof "@.:");
SAFE_ALLOCA (lock_info_str, char *, lock_info_size);
pid = getpid ();
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);
err = symlink (lock_info_str, lfname);
if (errno == EEXIST && force)
@ -372,6 +372,9 @@ lock_file_1 (char *lfname, int force)
err = symlink (lock_info_str, lfname);
}
symlink_errno = errno;
SAFE_FREE ();
errno = symlink_errno;
return err == 0;
}
@ -541,9 +544,11 @@ lock_file (Lisp_Object fn)
{
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;
/* Don't do locking while dumping Emacs.
Uncompressing wtmp files uses call-process, which does not work
@ -580,15 +585,17 @@ lock_file (Lisp_Object fn)
return;
/* Else consider breaking the lock */
locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host)
+ INT_STRLEN_BOUND (printmax_t)
+ sizeof "@ (pid )");
locker_size = (strlen (lock_info.user) + strlen (lock_info.host)
+ INT_STRLEN_BOUND (printmax_t)
+ sizeof "@ (pid )");
SAFE_ALLOCA (locker, char *, locker_size);
pid = 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);
attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker));
SAFE_FREE ();
if (!NILP (attack))
/* User says take the lock */
{

View file

@ -21,6 +21,7 @@ You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <float.h>
#include <stdio.h>
#include <ctype.h>
#include <setjmp.h>
@ -1180,7 +1181,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
char *p;
const char *f[XLFD_REGISTRY_INDEX + 1];
Lisp_Object val;
int i, j, len = 0;
int i, j, len;
font_assert (FONTP (font));
@ -1195,9 +1196,9 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
if (NILP (val))
{
if (j == XLFD_REGISTRY_INDEX)
f[j] = "*-*", len += 4;
f[j] = "*-*";
else
f[j] = "*", len += 2;
f[j] = "*";
}
else
{
@ -1207,21 +1208,15 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
&& ! strchr (SSDATA (val), '-'))
{
/* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */
if (SDATA (val)[SBYTES (val) - 1] == '*')
{
f[j] = p = alloca (SBYTES (val) + 3);
sprintf (p, "%s-*", SDATA (val));
len += SBYTES (val) + 3;
}
else
{
f[j] = p = alloca (SBYTES (val) + 4);
sprintf (p, "%s*-*", SDATA (val));
len += SBYTES (val) + 4;
}
ptrdiff_t alloc = SBYTES (val) + 4;
if (nbytes <= alloc)
return -1;
f[j] = p = alloca (alloc);
sprintf (p, "%s%s-*", SDATA (val),
"*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
}
else
f[j] = SSDATA (val), len += SBYTES (val) + 1;
f[j] = SSDATA (val);
}
}
@ -1230,11 +1225,11 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
{
val = font_style_symbolic (font, i, 0);
if (NILP (val))
f[j] = "*", len += 2;
f[j] = "*";
else
{
val = SYMBOL_NAME (val);
f[j] = SSDATA (val), len += SBYTES (val) + 1;
f[j] = SSDATA (val);
}
}
@ -1242,64 +1237,62 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
font_assert (NUMBERP (val) || NILP (val));
if (INTEGERP (val))
{
i = XINT (val);
if (i <= 0)
i = pixel_size;
if (i > 0)
EMACS_INT v = XINT (val);
if (v <= 0)
v = pixel_size;
if (v > 0)
{
f[XLFD_PIXEL_INDEX] = p = alloca (22);
len += sprintf (p, "%d-*", i) + 1;
f[XLFD_PIXEL_INDEX] = p =
alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
sprintf (p, "%"pI"d-*", v);
}
else
f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
f[XLFD_PIXEL_INDEX] = "*-*";
}
else if (FLOATP (val))
{
i = XFLOAT_DATA (val) * 10;
f[XLFD_PIXEL_INDEX] = p = alloca (12);
len += sprintf (p, "*-%d", i) + 1;
double v = XFLOAT_DATA (val) * 10;
f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1);
sprintf (p, "*-%.0f", v);
}
else
f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
f[XLFD_PIXEL_INDEX] = "*-*";
if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
{
i = XINT (AREF (font, FONT_DPI_INDEX));
f[XLFD_RESX_INDEX] = p = alloca (22);
len += sprintf (p, "%d-%d", i, i) + 1;
EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
f[XLFD_RESX_INDEX] = p =
alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
sprintf (p, "%"pI"d-%"pI"d", v, v);
}
else
f[XLFD_RESX_INDEX] = "*-*", len += 4;
f[XLFD_RESX_INDEX] = "*-*";
if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
{
int spacing = XINT (AREF (font, FONT_SPACING_INDEX));
EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p"
: spacing <= FONT_SPACING_DUAL ? "d"
: spacing <= FONT_SPACING_MONO ? "m"
: "c");
len += 2;
}
else
f[XLFD_SPACING_INDEX] = "*", len += 2;
f[XLFD_SPACING_INDEX] = "*";
if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
{
f[XLFD_AVGWIDTH_INDEX] = p = alloca (22);
len += sprintf (p, "%"pI"d",
XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1;
f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT));
sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
}
else
f[XLFD_AVGWIDTH_INDEX] = "*", len += 2;
len++; /* for terminating '\0'. */
if (len >= nbytes)
return -1;
return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
f[XLFD_AVGWIDTH_INDEX] = "*";
len = 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;
}
/* Parse NAME (null terminated) and store information in FONT
@ -1553,23 +1546,19 @@ int
font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
{
Lisp_Object family, foundry;
Lisp_Object tail, val;
Lisp_Object val;
int point_size;
int i;
ptrdiff_t len = 1;
char *p;
char *lim;
Lisp_Object styles[3];
const char *style_names[3] = { "weight", "slant", "width" };
char work[256];
family = AREF (font, FONT_FAMILY_INDEX);
if (! NILP (family))
{
if (SYMBOLP (family))
{
family = SYMBOL_NAME (family);
len += SBYTES (family);
}
family = SYMBOL_NAME (family);
else
family = Qnil;
}
@ -1580,7 +1569,6 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
if (XINT (val) != 0)
pixel_size = XINT (val);
point_size = -1;
len += 21; /* for ":pixelsize=NUM" */
}
else
{
@ -1588,80 +1576,91 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
abort ();
pixel_size = -1;
point_size = (int) XFLOAT_DATA (val);
len += 11; /* for "-NUM" */
}
foundry = AREF (font, FONT_FOUNDRY_INDEX);
if (! NILP (foundry))
{
if (SYMBOLP (foundry))
{
foundry = SYMBOL_NAME (foundry);
len += 9 + SBYTES (foundry); /* ":foundry=NAME" */
}
foundry = SYMBOL_NAME (foundry);
else
foundry = Qnil;
}
for (i = 0; i < 3; i++)
{
styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
if (! NILP (styles[i]))
len += sprintf (work, ":%s=%s", style_names[i],
SDATA (SYMBOL_NAME (styles[i])));
}
styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
len += sprintf (work, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
len += strlen (":spacing=100");
if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
len += strlen (":scalable=false"); /* or ":scalable=true" */
for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
{
Lisp_Object key = XCAR (XCAR (tail)), value = XCDR (XCAR (tail));
len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */
if (STRINGP (value))
len += SBYTES (value);
else if (INTEGERP (value))
len += sprintf (work, "%"pI"d", XINT (value));
else if (SYMBOLP (value))
len += (NILP (value) ? 5 : 4); /* for "false" or "true" */
}
if (len > nbytes)
return -1;
p = name;
lim = name + nbytes;
if (! NILP (family))
p += sprintf (p, "%s", SDATA (family));
{
int len = snprintf (p, lim - p, "%s", SSDATA (family));
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
if (point_size > 0)
{
if (p == name)
p += sprintf (p, "%d", point_size);
else
p += sprintf (p, "-%d", point_size);
int len = snprintf (p, lim - p, "-%d" + (p == name), point_size);
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
else if (pixel_size > 0)
p += sprintf (p, ":pixelsize=%d", pixel_size);
{
int len = snprintf (p, lim - p, ":pixelsize=%d", pixel_size);
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
p += sprintf (p, ":foundry=%s",
SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX))));
{
int len = snprintf (p, lim - p, ":foundry=%s",
SSDATA (SYMBOL_NAME (AREF (font,
FONT_FOUNDRY_INDEX))));
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
for (i = 0; i < 3; i++)
if (! NILP (styles[i]))
p += sprintf (p, ":%s=%s", style_names[i],
SDATA (SYMBOL_NAME (styles[i])));
{
int len = snprintf (p, lim - p, ":%s=%s", style_names[i],
SSDATA (SYMBOL_NAME (styles[i])));
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
p += sprintf (p, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
{
int len = snprintf (p, lim - p, ":dpi=%"pI"d",
XINT (AREF (font, FONT_DPI_INDEX)));
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
p += sprintf (p, ":spacing=%"pI"d", XINT (AREF (font, FONT_SPACING_INDEX)));
{
int len = snprintf (p, lim - p, ":spacing=%"pI"d",
XINT (AREF (font, FONT_SPACING_INDEX)));
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
{
if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0)
p += sprintf (p, ":scalable=true");
else
p += sprintf (p, ":scalable=false");
int len = snprintf (p, lim - p,
(XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
? ":scalable=true"
: ":scalable=false"));
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
return (p - name);
}
@ -1952,12 +1951,12 @@ generate_otf_features (Lisp_Object spec, char *features)
else if (! asterisk)
{
val = SYMBOL_NAME (val);
p += sprintf (p, "%s", SDATA (val));
p += esprintf (p, "%s", SDATA (val));
}
else
{
val = SYMBOL_NAME (val);
p += sprintf (p, "~%s", SDATA (val));
p += esprintf (p, "~%s", SDATA (val));
}
}
if (CONSP (spec))

View file

@ -1700,7 +1700,7 @@ FONT-SPEC is a vector, a cons, or a string. See the documentation of
static Lisp_Object auto_fontset_alist;
/* Number of automatically created fontsets. */
static int num_auto_fontsets;
static printmax_t num_auto_fontsets;
/* 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 @@ fontset_from_font (Lisp_Object font_object)
alias = intern ("fontset-startup");
else
{
char temp[32];
char temp[sizeof "fontset-auto" + INT_STRLEN_BOUND (printmax_t)];
sprintf (temp, "fontset-auto%d", num_auto_fontsets - 1);
sprintf (temp, "fontset-auto%"pMd, num_auto_fontsets - 1);
alias = intern (temp);
}
fontset_spec = copy_font_spec (font_spec);

View file

@ -497,7 +497,7 @@ make_minibuffer_frame (void)
/* Construct a frame that refers to a terminal. */
static int tty_frame_count;
static printmax_t tty_frame_count;
struct frame *
make_initial_frame (void)
@ -551,7 +551,7 @@ make_terminal_frame (struct terminal *terminal)
{
register struct frame *f;
Lisp_Object frame;
char name[20];
char name[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
if (!terminal->name)
error ("Terminal is not live, can't create new frames on it");
@ -562,7 +562,7 @@ make_terminal_frame (struct terminal *terminal)
Vframe_list = Fcons (frame, Vframe_list);
tty_frame_count++;
sprintf (name, "F%d", tty_frame_count);
sprintf (name, "F%"pMd, tty_frame_count);
f->name = build_string (name);
f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
@ -2074,7 +2074,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
/* If NAME is nil, set the name to F<num>. */
if (NILP (name))
{
char namebuf[20];
char namebuf[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
/* Check for no change needed in this very common case
before we do any consing. */
@ -2083,7 +2083,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
return;
tty_frame_count++;
sprintf (namebuf, "F%d", tty_frame_count);
sprintf (namebuf, "F%"pMd, tty_frame_count);
name = build_string (namebuf);
}
else
@ -3065,6 +3065,7 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
{
char buf[16];
Lisp_Object tem;
unsigned long w;
/* Represent negative positions (off the top or left screen edge)
in a way that Fmodify_frame_parameters will understand correctly. */
@ -3097,7 +3098,8 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
for non-toolkit scroll bar.
ruler-mode.el depends on this. */
: Qnil));
sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
w = 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 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
/* Tooltip frame may not have this widget. */
if (FRAME_X_OUTPUT (f)->widget)
#endif
sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
{
w = FRAME_OUTER_WINDOW (f);
sprintf (buf, "%lu", w);
}
store_in_alist (alistptr, Qouter_window_id,
build_string (buf));
#endif
@ -3576,13 +3581,13 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
void
validate_x_resource_name (void)
{
int len = 0;
ptrdiff_t len = 0;
/* Number of valid characters in the resource name. */
int good_count = 0;
ptrdiff_t good_count = 0;
/* Number of invalid characters in the resource name. */
int bad_count = 0;
ptrdiff_t bad_count = 0;
Lisp_Object new;
int i;
ptrdiff_t i;
if (!STRINGP (Vx_resource_class))
Vx_resource_class = build_string (EMACS_CLASS);
@ -3615,8 +3620,9 @@ validate_x_resource_name (void)
if (bad_count == 0)
return;
/* 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 = build_string ("emacs");
return;
@ -3745,20 +3751,24 @@ x_get_resource_string (const char *attribute, const char *class)
{
char *name_key;
char *class_key;
char *result;
struct frame *sf = SELECTED_FRAME ();
ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name);
USE_SAFE_ALLOCA;
/* Allocate space for the components, the dots which separate them,
and the final '\0'. */
name_key = (char *) alloca (SBYTES (Vinvocation_name)
+ strlen (attribute) + 2);
SAFE_ALLOCA (name_key, char *, invocation_namelen + strlen (attribute) + 2);
class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
+ strlen (class) + 2);
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);
return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
name_key, class_key);
result = x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
name_key, class_key);
SAFE_FREE ();
return result;
}
#endif

View file

@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#ifdef USE_GTK
#include <float.h>
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
@ -567,7 +568,7 @@ xg_check_special_colors (struct frame *f,
GtkStyleContext *gsty
= 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 = GTK_STATE_FLAG_SELECTED|GTK_STATE_FLAG_FOCUSED;
if (get_fg)
gtk_style_context_get_color (gsty, state, &col);
@ -797,7 +798,7 @@ xg_set_geometry (FRAME_PTR f)
int xneg = f->size_hint_flags & XNegative;
int top = f->top_pos;
int yneg = f->size_hint_flags & YNegative;
char geom_str[32];
char geom_str[sizeof "=x--" + 4 * INT_STRLEN_BOUND (int)];
if (xneg)
left = -left;

View file

@ -196,7 +196,7 @@ int immediate_quit;
int quit_char;
/* Current depth in recursive edits. */
int command_loop_level;
EMACS_INT command_loop_level;
/* 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 @@ static Lisp_Object
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)];
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
@ -1010,7 +1011,7 @@ cmd_error (Lisp_Object data)
if (executing_kbd_macro_iterations == 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 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
else if (STRINGP (name_alist_or_stem))
{
int len = SBYTES (name_alist_or_stem);
char *buf = (char *) alloca (len + 50);
sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
XINT (symbol_int) + 1);
char *buf;
ptrdiff_t len = (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 = intern (buf);
SAFE_FREE ();
}
else if (name_table != 0 && name_table[symbol_num])
value = intern (name_table[symbol_num]);
@ -6483,7 +6488,7 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
if (NILP (value))
{
char buf[20];
char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
sprintf (buf, "key-%"pI"d", symbol_num);
value = intern (buf);
}
@ -10382,19 +10387,21 @@ give to the command you invoke, if it asks for an argument. */)
char *newmessage;
int message_p = push_message ();
int count = SPECPDL_INDEX ();
ptrdiff_t newmessage_len, newmessage_alloc;
USE_SAFE_ALLOCA;
record_unwind_protect (pop_message_unwind, Qnil);
binding = Fkey_description (bindings, Qnil);
newmessage
= (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 =
(sizeof "You can run the command `' with "
+ SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
newmessage_len =
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 = sit_for (Vsuggest_key_bindings, 0, 2);
@ -10404,6 +10411,7 @@ give to the command you invoke, if it asks for an argument. */)
if (!NILP (waited) && message_p)
restore_message ();
SAFE_FREE ();
unbind_to (count, Qnil);
}
}
@ -10633,7 +10641,9 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
(void)
{
Lisp_Object temp;
XSETFASTINT (temp, command_loop_level + minibuf_level);
/* Wrap around reliably on integer overflow. */
EMACS_INT sum = (command_loop_level & INTMASK) + (minibuf_level & INTMASK);
XSETINT (temp, sum);
return temp;
}

View file

@ -2143,12 +2143,12 @@ spaces are put between sequence elements, etc. */)
char *
push_key_description (register unsigned int c, register char *p, int force_multibyte)
push_key_description (EMACS_INT ch, char *p, int force_multibyte)
{
unsigned c2;
int c, c2;
/* Clear all the meaningless bits above the meta bit. */
c &= meta_modifier | ~ - meta_modifier;
c = ch & (meta_modifier | ~ - meta_modifier);
c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
| meta_modifier | shift_modifier | super_modifier);
@ -2283,10 +2283,15 @@ around function keys and event symbols. */)
{
if (NILP (no_angles))
{
char *buffer
= (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 = build_string (buffer);
SAFE_FREE ();
return result;
}
else
return Fsymbol_name (key);

View file

@ -2895,6 +2895,14 @@ extern void syms_of_print (void);
/* 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 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);
/* Defined in lread.c. */
extern Lisp_Object Qvariable_documentation, Qstandard_input;
@ -3186,7 +3194,7 @@ EXFUN (Fread_minibuffer, 2);
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);
@ -3250,7 +3258,7 @@ extern void force_auto_save_soon (void);
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);
/* Defined in indent.c */

View file

@ -4295,14 +4295,20 @@ init_lread (void)
void
dir_warning (const char *format, Lisp_Object dirname)
{
char *buffer
= (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 = esprintf (buffer, format, SDATA (dirname));
message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname));
SAFE_FREE ();
}
}
void

View file

@ -35,7 +35,7 @@ static Lisp_Object Qkbd_macro_termination_hook;
This is not bound at each level,
so after an error, it describes the innermost interrupted macro. */
int executing_kbd_macro_iterations;
EMACS_INT executing_kbd_macro_iterations;
/* This is the macro that was executing.
This is not bound at each level,
@ -175,11 +175,11 @@ each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */)
if (XFASTINT (repeat) == 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, loopfunc);
Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro),
repeat, loopfunc);
}
return Qnil;
}
@ -302,9 +302,9 @@ each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */)
Lisp_Object final;
Lisp_Object tem;
int pdlcount = SPECPDL_INDEX ();
int repeat = 1;
EMACS_INT repeat = 1;
struct gcpro gcpro1, gcpro2;
int success_count = 0;
EMACS_INT success_count = 0;
executing_kbd_macro_iterations = 0;

View file

@ -22,7 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
This is not bound at each level,
so after an error, it describes the innermost interrupted macro. */
extern int executing_kbd_macro_iterations;
extern EMACS_INT executing_kbd_macro_iterations;
/* This is the macro that was executing.
This is not bound at each level,
@ -42,4 +42,3 @@ extern void finalize_kbd_macro_chars (void);
/* Store a character into kbd macro being defined */
extern void store_kbd_macro_char (Lisp_Object);

View file

@ -49,7 +49,7 @@ static Lisp_Object minibuf_save_list;
/* Depth in minibuffer invocations. */
int minibuf_level;
EMACS_INT minibuf_level;
/* The maximum length of a minibuffer history. */
@ -772,10 +772,10 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
used for nonrecursive minibuffer invocations. */
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)];
XSETFASTINT (num, depth);
tail = Fnthcdr (num, Vminibuffer_list);
@ -787,7 +787,7 @@ get_minibuffer (int depth)
buf = Fcar (tail);
if (NILP (buf) || NILP (BVAR (XBUFFER (buf), name)))
{
sprintf (name, " *Minibuf-%d*", depth);
sprintf (name, " *Minibuf-%"pI"d*", depth);
buf = Fget_buffer_create (build_string (name));
/* Although the buffer's name starts with a space, undo should be

View file

@ -5316,7 +5316,7 @@ - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
strcpy (old_title, t);
}
size_title = xmalloc (strlen (old_title) + 40);
sprintf (size_title, "%s — (%d x %d)", old_title, cols, rows);
esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows);
[window setTitle: [NSString stringWithUTF8String: size_title]];
[window display];
xfree (size_title);

View file

@ -1016,12 +1016,15 @@ float_to_string (char *buf, double data)
{
width = 0;
do
width = (width * 10) + (*cp++ - '0');
{
width = (width * 10) + (*cp++ - '0');
if (DBL_DIG < width)
goto lose;
}
while (*cp >= '0' && *cp <= '9');
/* A precision of zero is valid only for %f. */
if (width > DBL_DIG
|| (width == 0 && *cp != 'f'))
if (width == 0 && *cp != 'f')
goto lose;
}
@ -1314,7 +1317,9 @@ print_prune_string_charset (Lisp_Object string)
static void
print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag)
{
char buf[40];
char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT),
max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t),
40))];
QUIT;
@ -1614,8 +1619,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
PRINTCHAR ('(');
{
EMACS_INT print_length;
int i;
printmax_t i, print_length;
Lisp_Object halftail = obj;
/* Negative values of print-length are invalid in CL.
@ -1623,7 +1627,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
if (NATNUMP (Vprint_length))
print_length = XFASTINT (Vprint_length);
else
print_length = 0;
print_length = TYPE_MAXIMUM (printmax_t);
i = 0;
while (CONSP (obj))
@ -1634,7 +1638,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
/* Simple but imcomplete way. */
if (i != 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 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
}
}
if (i++)
if (i)
PRINTCHAR (' ');
if (print_length && i > print_length)
if (print_length <= i)
{
strout ("...", 3, 3, printcharfun);
goto end_of_list;
}
i++;
print_object (XCAR (obj), printcharfun, escapeflag);
obj = XCDR (obj);
@ -1798,19 +1803,17 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
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);
if (!NILP (h->test))
@ -2038,7 +2041,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
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);

View file

@ -616,8 +616,8 @@ make_process (Lisp_Object name)
{
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;
p = allocate_process ();
@ -651,7 +651,7 @@ make_process (Lisp_Object name)
{
tem = Fget_process (name1);
if (NILP (tem)) break;
sprintf (suffix, "<%d>", i);
sprintf (suffix, "<%"pMd">", i);
name1 = concat2 (name, build_string (suffix));
}
name = name1;

View file

@ -1811,6 +1811,45 @@ strerror (int errnum)
}
#endif /* not WINDOWSNT */
#endif /* ! HAVE_STRERROR */
#ifndef HAVE_SNPRINTF
/* Approximate snprintf as best we can on ancient hosts that lack it. */
int
snprintf (char *buf, size_t bufsize, char const *format, ...)
{
ptrdiff_t size = min (bufsize, PTRDIFF_MAX);
ptrdiff_t nbytes = size - 1;
va_list ap;
if (size)
{
va_start (ap, format);
nbytes = doprnt (buf, size, format, 0, ap);
va_end (ap);
}
if (nbytes == size - 1)
{
/* Calculate the length of the string that would have been created
had the buffer been large enough. */
char stackbuf[4000];
char *b = stackbuf;
ptrdiff_t bsize = sizeof stackbuf;
va_start (ap, format);
nbytes = evxprintf (&b, &bsize, stackbuf, -1, format, ap);
va_end (ap);
if (b != stackbuf)
xfree (b);
}
if (INT_MAX < nbytes)
{
errno = EOVERFLOW;
return -1;
}
return nbytes;
}
#endif
int
emacs_open (const char *path, int oflag, int mode)

View file

@ -1817,7 +1817,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
{
int face_id;
int len;
char buf[9];
char buf[sizeof "\\x" + max (6, (sizeof it->c * CHAR_BIT + 3) / 4)];
char const *str = " ";
/* Get a face ID for the glyph by utilizing a cache (the same way as

View file

@ -847,11 +847,11 @@ extern Lisp_Object echo_area_window;
/* Depth in recursive edits. */
extern int command_loop_level;
extern EMACS_INT command_loop_level;
/* Depth in minibuffer invocations. */
extern int minibuf_level;
extern EMACS_INT minibuf_level;
/* true if we should redraw the mode lines on the next redisplay. */

View file

@ -3549,6 +3549,8 @@ x_update_menu_appearance (struct frame *f)
rdb != NULL))
{
char line[512];
char *buf = line;
ptrdiff_t bufsize = sizeof line;
Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
const char *myname = SSDATA (Vx_resource_name);
@ -3561,24 +3563,25 @@ x_update_menu_appearance (struct frame *f)
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 = 1;
}
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 = 1;
}
@ -3616,11 +3619,12 @@ x_update_menu_appearance (struct frame *f)
#else
char *fontsetname = 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 = 1;
if (fontsetname != SSDATA (xlfd))
@ -3630,6 +3634,9 @@ x_update_menu_appearance (struct frame *f)
if (changed_p && f->output_data.x->menubar_widget)
free_frame_menubar (f);
if (buf != line)
xfree (buf);
}
}

View file

@ -2440,7 +2440,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
/* Do some needed geometry management. */
{
ptrdiff_t len;
char *tem, shell_position[32];
char *tem, shell_position[sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)];
Arg gal[10];
int gac = 0;
int extra_borders = 0;

View file

@ -7900,7 +7900,8 @@ x_io_error_quitter (Display *display)
{
char buf[256];
sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
snprintf (buf, sizeof buf, "Connection lost to X server `%s'",
DisplayString (display));
x_connection_closed (display, buf);
return 0;
}

View file

@ -955,7 +955,8 @@ XrmDatabase x_load_resources (Display *, const char *, const char *,
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);