* src/doprnt.c (esnprintf): Remove. All uses removed.

Suggested by Chong Yidong in <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9412#23>.
This commit is contained in:
Paul Eggert 2011-09-01 07:44:49 -07:00
parent 726cfaae86
commit 8666506ecd
7 changed files with 115 additions and 83 deletions

View file

@ -1,9 +1,9 @@
2011-08-31 Paul Eggert <eggert@cs.ucla.edu>
2011-09-01 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, esnprintf, exprintf, evxprintf): New functions.
(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
@ -17,7 +17,7 @@
* 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.
(esprintf, exprintf, evxprintf): New decls.
* window.h (command_loop_level, minibuf_level): Reflect API changes.
* dbusbind.c (signature_cat): New function.
@ -43,7 +43,7 @@
* 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 esnprintf to count
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.
@ -102,9 +102,6 @@
to avoid potential buffer overrun.
* xterm.c (x_io_error_quitter): Don't overrun sprintf buffer.
(x_term_init): Use sprintf, not snprintf, so that we need not
worry about ancient hosts that lack snprintf. The buffer cannot
possibly be overrun, so this is safe.
* xterm.h (x_check_errors): Add ATTRIBUTE_FORMAT_PRINTF.

View file

@ -284,6 +284,7 @@ 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;
@ -365,9 +366,9 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
elt = CDR_SAFE (XD_NEXT_VALUE (elt));
}
if (esnprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
"%c%s", dtype, subsig)
== DBUS_MAXIMUM_SIGNATURE_LENGTH - 1)
subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
"%c%s", dtype, subsig);
if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH))
string_overflow ();
break;
@ -2088,32 +2089,45 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
connection = xd_initialize (bus, TRUE);
/* Create a rule to receive related signals. */
rulelen = esnprintf (rule, sizeof 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))
rulelen += esnprintf (rule + rulelen, sizeof rule - rulelen,
{
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))
rulelen += esnprintf (rule + rulelen, sizeof rule - rulelen,
{
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]);
rulelen += esnprintf (rule + rulelen, sizeof rule - rulelen,
",arg%"pD"d='%s'", i - 6, SDATA (args[i]));
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;
}
if (rulelen == sizeof rule - 1)
string_overflow ();
/* Add the rule to the bus. */
dbus_error_init (&derror);
dbus_bus_add_match (connection, rule, &derror);

View file

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

@ -486,27 +486,6 @@ esprintf (char *buf, char const *format, ...)
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 = 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

View file

@ -1285,14 +1285,14 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
}
else
f[XLFD_AVGWIDTH_INDEX] = "*";
len = esnprintf (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 - 1 ? -1 : len;
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
@ -1593,31 +1593,75 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
p = name;
lim = name + nbytes;
if (! NILP (family))
p += esnprintf (p, lim - p, "%s", SSDATA (family));
{
int len = snprintf (p, lim - p, "%s", SSDATA (family));
if (! (0 <= len && len < lim - p))
return -1;
p += len;
}
if (point_size > 0)
p += esnprintf (p, lim - p, "-%d" + (p == name), 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 += esnprintf (p, lim - 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 += esnprintf (p, lim - p, ":foundry=%s",
SSDATA (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 += esnprintf (p, lim - p, ":%s=%s", style_names[i],
SSDATA (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 += esnprintf (p, lim - 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 += esnprintf (p, lim - 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)))
p += esnprintf (p, lim - p,
(XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
? ":scalable=true"
: ":scalable=false"));
return lim - p == 1 ? -1 : p - name;
{
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);
}
/* Parse NAME (null terminated) and store information in FONT

View file

@ -2897,8 +2897,6 @@ 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);

View file

@ -7900,8 +7900,8 @@ x_io_error_quitter (Display *display)
{
char buf[256];
esnprintf (buf, sizeof 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;
}
@ -10278,8 +10278,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
atom_names[i] = (char *) atom_refs[i].name;
/* Build _XSETTINGS_SN atom name */
sprintf (xsettings_atom_name,
"_XSETTINGS_S%d", XScreenNumberOfScreen (dpyinfo->screen));
snprintf (xsettings_atom_name, sizeof (xsettings_atom_name),
"_XSETTINGS_S%d", XScreenNumberOfScreen (dpyinfo->screen));
atom_names[i] = xsettings_atom_name;
XInternAtoms (dpyinfo->display, atom_names, total_atom_count,