From 2db4c7f0b377c98c402a49cc60aa174f3fa8b853 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 25 Jun 2021 11:05:21 +0200 Subject: [PATCH] hexdump: do not use atoi() Addresses: https://github.com/karelzak/util-linux/issues/1358 Signed-off-by: Karel Zak --- text-utils/hexdump-parse.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/text-utils/hexdump-parse.c b/text-utils/hexdump-parse.c index 0b460a70d..1d2e689b6 100644 --- a/text-utils/hexdump-parse.c +++ b/text-utils/hexdump-parse.c @@ -98,6 +98,18 @@ void addfile(char *name, struct hexdump *hex) fclose(fp); } +static char *next_number(const char *str, int *num) +{ + char *end = NULL; + + errno = 0; + *num = strtol(str, &end, 10); + + if (errno || !end || end == str) + return NULL; + return end; +} + void add_fmt(const char *fmt, struct hexdump *hex) { const char *p, *savep; @@ -127,13 +139,11 @@ void add_fmt(const char *fmt, struct hexdump *hex) /* If leading digit, repetition count. */ if (isdigit(*p)) { - savep = p; - while (isdigit(*p)) - p++; - if (!isspace(*p) && *p != '/') + p = next_number(p, &tfu->reps); + if (!p || (!isspace(*p) && *p != '/')) badfmt(fmt); + /* may overwrite either white space or slash */ - tfu->reps = atoi(savep); tfu->flags = F_SETREP; /* skip trailing white space */ p = skip_space(++p); @@ -145,12 +155,9 @@ void add_fmt(const char *fmt, struct hexdump *hex) /* byte count */ if (isdigit(*p)) { - savep = p; - while (isdigit(*p)) - p++; - if (!isspace(*p)) + p = next_number(p, &tfu->bcnt); + if (!p || !isspace(*p)) badfmt(fmt); - tfu->bcnt = atoi(savep); /* skip trailing white space */ p = skip_space(++p); } @@ -199,11 +206,8 @@ int block_size(struct hexdump_fs *fs) */ while (strchr(spec + 1, *++fmt)) ; - if (*fmt == '.' && isdigit(*++fmt)) { - prec = atoi(fmt); - while (isdigit(*++fmt)) - ; - } + if (*fmt == '.' && isdigit(*++fmt)) + fmt = next_number(fmt, &prec); if (first_letter(fmt, "diouxX")) bcnt += 4; else if (first_letter(fmt, "efgEG")) @@ -269,9 +273,7 @@ void rewrite_rules(struct hexdump_fs *fs, struct hexdump *hex) ; if (*p1 == '.' && isdigit(*++p1)) { sokay = USEPREC; - prec = atoi(p1); - while (isdigit(*++p1)) - ; + p1 = next_number(p1, &prec); } else sokay = NOTOKAY; }