Commit c2d1e36d authored by Paul Eggert's avatar Paul Eggert

* doprnt.c: Prefer signed to unsigned when either works.

* eval.c (verror):
* doprnt.c (doprnt):
* lisp.h (doprnt):
* xdisp.c (vmessage):
Use ptrdiff_t, not size_t, when using or implementing doprnt,
since the sizes cannot exceed ptrdiff_t bounds anyway, and we
prefer signed arithmetic to avoid comparison confusion.
* doprnt.c (doprnt): Avoid a "+ 1" that can't overflow,
but is a bit tricky.
parent 0e926e56
2011-07-07 Paul Eggert <eggert@cs.ucla.edu>
* doprnt.c: Prefer signed to unsigned when either works.
* eval.c (verror):
* doprnt.c (doprnt):
* lisp.h (doprnt):
* xdisp.c (vmessage):
Use ptrdiff_t, not size_t, when using or implementing doprnt,
since the sizes cannot exceed ptrdiff_t bounds anyway, and we
prefer signed arithmetic to avoid comparison confusion.
* doprnt.c (doprnt): Avoid a "+ 1" that can't overflow,
but is a bit tricky.
Assume freestanding C89 headers, string.h, stdlib.h.
* data.c, doprnt.c, floatfns.c, print.c:
Include float.h unconditionally.
......
......@@ -129,8 +129,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
String arguments are passed as C strings.
Integers are passed as C integers. */
size_t
doprnt (char *buffer, register size_t bufsize, const char *format,
ptrdiff_t
doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
const char *format_end, va_list ap)
{
const char *fmt = format; /* Pointer into format string */
......@@ -140,7 +140,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
char tembuf[DBL_MAX_10_EXP + 100];
/* Size of sprintf_buffer. */
size_t size_allocated = sizeof (tembuf);
ptrdiff_t size_allocated = sizeof (tembuf);
/* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */
char *sprintf_buffer = tembuf;
......@@ -159,7 +159,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
if (format_end == 0)
format_end = format + strlen (format);
if ((format_end - format + 1) < sizeof (fixed_buffer))
if (format_end - format < sizeof (fixed_buffer) - 1)
fmtcpy = fixed_buffer;
else
SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
......@@ -171,7 +171,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
{
if (*fmt == '%') /* Check for a '%' character */
{
size_t size_bound = 0;
ptrdiff_t size_bound = 0;
EMACS_INT width; /* Columns occupied by STRING on display. */
int long_flag = 0;
int pIlen = sizeof pI - 1;
......@@ -189,16 +189,16 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
This might be a field width or a precision; e.g.
%1.1000f and %1000.1f both might need 1000+ bytes.
Parse the width or precision, checking for overflow. */
size_t n = *fmt - '0';
ptrdiff_t n = *fmt - '0';
while (fmt + 1 < format_end
&& '0' <= fmt[1] && fmt[1] <= '9')
{
/* Avoid size_t overflow. Avoid int overflow too, as
/* Avoid ptrdiff_t, size_t, and int overflow, as
many sprintfs mishandle widths greater than INT_MAX.
This test is simple but slightly conservative: e.g.,
(INT_MAX - INT_MAX % 10) is reported as an overflow
even when it's not. */
if (n >= min (INT_MAX, SIZE_MAX) / 10)
if (n >= min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / 10)
error ("Format width or precision too large");
n = n * 10 + fmt[1] - '0';
*string++ = *++fmt;
......@@ -230,7 +230,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
/* Make the size bound large enough to handle floating point formats
with large numbers. */
if (size_bound > SIZE_MAX - DBL_MAX_10_EXP - 50)
if (size_bound > min (PTRDIFF_MAX, SIZE_MAX) - DBL_MAX_10_EXP - 50)
error ("Format width or precision too large");
size_bound += DBL_MAX_10_EXP + 50;
......
......@@ -1968,18 +1968,18 @@ void
verror (const char *m, va_list ap)
{
char buf[4000];
size_t size = sizeof buf;
size_t size_max = STRING_BYTES_BOUND + 1;
size_t mlen = strlen (m);
ptrdiff_t size = sizeof buf;
ptrdiff_t size_max = STRING_BYTES_BOUND + 1;
char const *m_end = m + strlen (m);
char *buffer = buf;
size_t used;
ptrdiff_t used;
Lisp_Object string;
while (1)
{
va_list ap_copy;
va_copy (ap_copy, ap);
used = doprnt (buffer, size, m, m + mlen, ap_copy);
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
......
......@@ -2868,7 +2868,8 @@ extern void float_to_string (char *, double);
extern void syms_of_print (void);
/* Defined in doprnt.c */
extern size_t doprnt (char *, size_t, const char *, const char *, va_list);
extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *,
va_list);
/* Defined in lread.c. */
extern Lisp_Object Qvariable_documentation, Qstandard_input;
......
......@@ -8485,7 +8485,7 @@ vmessage (const char *m, va_list ap)
{
if (m)
{
size_t len;
ptrdiff_t len;
len = doprnt (FRAME_MESSAGE_BUF (f),
FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment