logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/
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:

Mcmd/expr.y23++++++++++++-----------
Mtest-cmd/expr.sh5++++-
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