commit: 78fcb7b90d11100be507ea8a9870a5a5cdc37920
parent 40c908cd00a9f61fc669ff92ced34b99f7423f3f
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Thu, 24 Apr 2025 21:37:33 +0200
cmd/expr: use snprintf instead of length estimate + sprintf
Diffstat:
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/cmd/expr.y b/cmd/expr.y
@@ -202,22 +202,23 @@ assert_to_integer(struct val *vp)
static void
to_string(struct val *vp)
{
- char *tmp;
-
if (vp->type == string || vp->type == numeric_string)
return;
- /*
- * log_10(x) ~= 0.3 * log_2(x). Rounding up gives the number
- * of digits; add one each for the sign and terminating null
- * character, respectively.
- */
-#define NDIGITS(x) (3 * (sizeof(x) * CHAR_BIT) / 10 + 1 + 1 + 1)
- tmp = malloc(NDIGITS(vp->u.i));
+ int ndigits = snprintf(NULL, 0, "%jd", vp->u.i);
+ if(ndigits < 0)
+ utils_errx(ERR_EXIT, "failed to pre-format integer %jd as a string", vp->u.i);
+
+ ndigits++; // NULL terminator
+
+ char *tmp = malloc(ndigits);
if (tmp == NULL)
- utils_errx(ERR_EXIT, "malloc() failed");
+ utils_errx(ERR_EXIT, "malloc(%zd) for to_string() failed", ndigits);
+
+ int ret = snprintf(tmp, ndigits, "%jd", vp->u.i);
+ if(ret < 0)
+ utils_errx(ERR_EXIT, "failed to format integer %jd as a string", vp->u.i);
- sprintf(tmp, "%jd", vp->u.i);
vp->type = string;
vp->u.s = tmp;
}
diff --git a/test-cmd/expr.sh b/test-cmd/expr.sh
@@ -4,7 +4,7 @@
WD="$(dirname "$0")/../"
target="${WD}/cmd/expr"
-plans=41
+plans=43
. "${WD}/test-cmd/tap.sh"
@@ -80,3 +80,6 @@ t_args add '3
' 1 + 2
t_args sub '2
' 3 - 1
+
+t_expr_no to_string_int_no '(' 0 : 0 ')' = 'foo'
+t_expr_ok to_string_int_ok '(' 'f00bar' : 'f[0-9][0-9]bar' ')' : 6