Merge pull request #15 from melloc/fmt-overflow
Protect against overflowing during OFMT/CONVFMT conversions
diff --git a/bugs-fixed/README b/bugs-fixed/README
index 629db08..51e8a4e 100644
--- a/bugs-fixed/README
+++ b/bugs-fixed/README
@@ -26,3 +26,9 @@
8. missing-precision: When using the format string "%*s", the precision
argument was used without checking if it was present first.
+
+9. fmt-overflow: The buffer used for OFMT/CONVFMT conversions was written
+to with sprintf(), which meant that some conversions could write past the
+end.
+
+
diff --git a/bugs-fixed/fmt-overflow.awk b/bugs-fixed/fmt-overflow.awk
new file mode 100644
index 0000000..bf5877e
--- /dev/null
+++ b/bugs-fixed/fmt-overflow.awk
@@ -0,0 +1 @@
+BEGIN { OFMT = "%.1000f"; print 1.25; }
diff --git a/bugs-fixed/fmt-overflow.ok b/bugs-fixed/fmt-overflow.ok
new file mode 100644
index 0000000..5f7449e
--- /dev/null
+++ b/bugs-fixed/fmt-overflow.ok
@@ -0,0 +1 @@
+1.2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/tran.c b/tran.c
index 72ca6ff..6775b01 100644
--- a/tran.c
+++ b/tran.c
@@ -395,7 +395,7 @@
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;
if ((vp->tval & (NUM | STR)) == 0)
@@ -434,9 +434,9 @@
if (freeable(vp)) \
xfree(vp->sval); \
if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \
- sprintf(s, "%.30g", vp->fval); \
+ snprintf(s, sizeof (s), "%.30g", vp->fval); \
else \
- sprintf(s, *fmt, vp->fval); \
+ snprintf(s, sizeof (s), *fmt, vp->fval); \
vp->sval = tostring(s); \
vp->tval &= ~DONTFREE; \
vp->tval |= STR; \