Correct some buffer sizes.

- __vfprintf()'s 'buf' has never been used for floating point, so
  don't define it in terms of (incorrect) constants describing
  floating point numbers.  The actual size needed depends on
  sizeof(uintmax_t) and locale details, so I slightly overestimated.

- We don't need a 308-character buffer to store the string "308".
  With long doubles and %a we need more than three characters, though.
This commit is contained in:
David Schultz 2003-04-05 22:03:43 +00:00
parent cdb06eda66
commit 38cac8f88b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113142
3 changed files with 42 additions and 23 deletions

View File

@ -41,7 +41,14 @@
* Floating point scanf/printf (input/output) definitions.
*/
/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
#define MAXEXP 308
/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
#define MAXFRACT 39
/*
* MAXEXPDIG is the maximum number of decimal digits needed to store a
* floating point exponent in the largest supported format. It should
* be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point
* conversions are supported, ceil(log10(LDBL_MAX_EXP)). But since it
* is presently never greater than 5 in practice, we fudge it.
*/
#define MAXEXPDIG 6
#if LDBL_MAX_EXP > 999999
#error "floating point buffers too small"
#endif

View File

@ -410,7 +410,6 @@ vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
#include <math.h>
#include "floatio.h"
#define BUF ((MAXEXP*2)+MAXFRACT+1) /* + decimal point */
#define DEFPREC 6
extern char *__dtoa(double, int, int, int *, int *, char **);
@ -419,12 +418,17 @@ extern void __freedtoa(char *s);
static char *cvt(double, int, int, char *, int *, int, int *);
static int exponent(char *, int, int);
#else /* no FLOATING_POINT */
#define BUF 136
#endif /* FLOATING_POINT */
/*
* The size of the buffer we use as scratch space for integer
* conversions, among other things. Technically, we would need the
* most space for base 10 conversions with thousands' grouping
* characters between each pair of digits. 100 bytes is a
* conservative overestimate even for a 128-bit uintmax_t.
*/
#define BUF 100
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
/*
@ -471,7 +475,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
int expt; /* integer value of exponent */
int expsize; /* character count for expstr */
int ndig; /* actual number of digits returned by cvt */
char expstr[7]; /* buffer for exponent string */
char expstr[MAXEXPDIG+2]; /* buffer for exponent string */
char *dtoaresult; /* buffer allocated by dtoa */
#endif
u_long ulval; /* integer arguments %[diouxX] */
@ -485,7 +489,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
char buf[BUF]; /* space for %c, %[diouxX], %[eEfFgG] */
char buf[BUF]; /* buffer with space for digits of uintmax_t */
char ox[2]; /* space for 0x hex-prefix */
union arg *argtable; /* args, built due to positional arg */
union arg statargtable [STATIC_ARG_TBL_SIZE];
@ -1022,6 +1026,8 @@ number: if ((dprec = prec) >= 0)
grouping);
}
size = buf + BUF - cp;
if (size > BUF) /* should never happen */
abort();
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
@ -1553,7 +1559,7 @@ static int
exponent(char *p0, int exp, int fmtch)
{
char *p, *t;
char expbuf[MAXEXP];
char expbuf[MAXEXPDIG];
p = p0;
*p++ = fmtch;
@ -1563,13 +1569,13 @@ exponent(char *p0, int exp, int fmtch)
}
else
*p++ = '+';
t = expbuf + MAXEXP;
t = expbuf + MAXEXPDIG;
if (exp > 9) {
do {
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
for (; t < expbuf + MAXEXP; *p++ = *t++);
for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
}
else {
*p++ = '0';

View File

@ -403,7 +403,6 @@ vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap)
#include <math.h>
#include "floatio.h"
#define BUF ((MAXEXP*2)+MAXFRACT+1) /* + decimal point */
#define DEFPREC 6
extern char *__dtoa(double, int, int, int *, int *, char **);
@ -412,12 +411,17 @@ extern void __freedtoa(char *s);
static wchar_t *cvt(double, int, int, char *, int *, wchar_t, int *);
static int exponent(wchar_t *, int, wchar_t);
#else /* no FLOATING_POINT */
#define BUF 136
#endif /* FLOATING_POINT */
/*
* The size of the buffer we use as scratch space for integer
* conversions, among other things. Technically, we would need the
* most space for base 10 conversions with thousands' grouping
* characters between each pair of digits. 100 bytes is a
* conservative overestimate even for a 128-bit uintmax_t.
*/
#define BUF 100
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
/*
@ -474,7 +478,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
int size; /* size of converted field or string */
int prsize; /* max size of printed field */
wchar_t *xdigs; /* digits for [xX] conversion */
wchar_t buf[BUF]; /* space for %c, %[diouxX], %[eEfFgG] */
wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */
wchar_t ox[2]; /* space for 0x hex-prefix */
union arg *argtable; /* args, built due to positional arg */
union arg statargtable [STATIC_ARG_TBL_SIZE];
@ -988,6 +992,8 @@ number: if ((dprec = prec) >= 0)
grouping);
}
size = buf + BUF - cp;
if (size > BUF) /* should never happen */
abort();
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
@ -1524,7 +1530,7 @@ static int
exponent(wchar_t *p0, int exp, wchar_t fmtch)
{
wchar_t *p, *t;
wchar_t expbuf[MAXEXP];
wchar_t expbuf[MAXEXPDIG];
p = p0;
*p++ = fmtch;
@ -1534,13 +1540,13 @@ exponent(wchar_t *p0, int exp, wchar_t fmtch)
}
else
*p++ = '+';
t = expbuf + MAXEXP;
t = expbuf + MAXEXPDIG;
if (exp > 9) {
do {
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
for (; t < expbuf + MAXEXP; *p++ = *t++);
for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
}
else {
*p++ = '0';