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:
parent
cdb06eda66
commit
38cac8f88b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113142
@ -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
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user