Protect against overflowing during OFMT/CONVFMT conversions

This commit is contained in:
Cody Peter Mello 2018-09-14 19:56:34 -07:00
parent 2dc7e5ff1a
commit e059b3b197
4 changed files with 9 additions and 3 deletions

View File

@ -23,3 +23,7 @@ and also if CONVFMT changed.
7. unary-plus: Unary plus on a string constant returned the string. 7. unary-plus: Unary plus on a string constant returned the string.
Instead, it should convert the value to numeric and give that value. Instead, it should convert the value to numeric and give that value.
X. fmt-overflow: The buffer used for OFMT/CONVFMT conversions was written
to with sprintf(), which meant that some conversions could write past the
end.

View File

@ -0,0 +1 @@
BEGIN { OFMT = "%.1000f"; print 1.25; }

View File

@ -0,0 +1 @@
1.2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

6
tran.c
View File

@ -395,7 +395,7 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
{ {
char s[100]; /* BUG: unchecked */ char s[256];
double dtemp; double dtemp;
if ((vp->tval & (NUM | STR)) == 0) if ((vp->tval & (NUM | STR)) == 0)
@ -434,9 +434,9 @@ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cel
if (freeable(vp)) \ if (freeable(vp)) \
xfree(vp->sval); \ xfree(vp->sval); \
if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \ if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \
sprintf(s, "%.30g", vp->fval); \ snprintf(s, sizeof (s), "%.30g", vp->fval); \
else \ else \
sprintf(s, *fmt, vp->fval); \ snprintf(s, sizeof (s), *fmt, vp->fval); \
vp->sval = tostring(s); \ vp->sval = tostring(s); \
vp->tval &= ~DONTFREE; \ vp->tval &= ~DONTFREE; \
vp->tval |= STR; \ vp->tval |= STR; \