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; \