hexdump: do not use atoi()

Addresses: https://github.com/karelzak/util-linux/issues/1358
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2021-06-25 11:05:21 +02:00
parent 0461279ab3
commit ccedcc55e1
1 changed files with 20 additions and 18 deletions

View File

@ -98,6 +98,18 @@ void addfile(char *name, struct hexdump *hex)
fclose(fp); 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) void add_fmt(const char *fmt, struct hexdump *hex)
{ {
const char *p, *savep; const char *p, *savep;
@ -127,13 +139,11 @@ void add_fmt(const char *fmt, struct hexdump *hex)
/* If leading digit, repetition count. */ /* If leading digit, repetition count. */
if (isdigit(*p)) { if (isdigit(*p)) {
savep = p; p = next_number(p, &tfu->reps);
while (isdigit(*p)) if (!p || (!isspace(*p) && *p != '/'))
p++;
if (!isspace(*p) && *p != '/')
badfmt(fmt); badfmt(fmt);
/* may overwrite either white space or slash */ /* may overwrite either white space or slash */
tfu->reps = atoi(savep);
tfu->flags = F_SETREP; tfu->flags = F_SETREP;
/* skip trailing white space */ /* skip trailing white space */
p = skip_space(++p); p = skip_space(++p);
@ -145,12 +155,9 @@ void add_fmt(const char *fmt, struct hexdump *hex)
/* byte count */ /* byte count */
if (isdigit(*p)) { if (isdigit(*p)) {
savep = p; p = next_number(p, &tfu->bcnt);
while (isdigit(*p)) if (!p || !isspace(*p))
p++;
if (!isspace(*p))
badfmt(fmt); badfmt(fmt);
tfu->bcnt = atoi(savep);
/* skip trailing white space */ /* skip trailing white space */
p = skip_space(++p); p = skip_space(++p);
} }
@ -199,11 +206,8 @@ int block_size(struct hexdump_fs *fs)
*/ */
while (strchr(spec + 1, *++fmt)) while (strchr(spec + 1, *++fmt))
; ;
if (*fmt == '.' && isdigit(*++fmt)) { if (*fmt == '.' && isdigit(*++fmt))
prec = atoi(fmt); fmt = next_number(fmt, &prec);
while (isdigit(*++fmt))
;
}
if (first_letter(fmt, "diouxX")) if (first_letter(fmt, "diouxX"))
bcnt += 4; bcnt += 4;
else if (first_letter(fmt, "efgEG")) else if (first_letter(fmt, "efgEG"))
@ -269,9 +273,7 @@ void rewrite_rules(struct hexdump_fs *fs, struct hexdump *hex)
; ;
if (*p1 == '.' && isdigit(*++p1)) { if (*p1 == '.' && isdigit(*++p1)) {
sokay = USEPREC; sokay = USEPREC;
prec = atoi(p1); p1 = next_number(p1, &prec);
while (isdigit(*++p1))
;
} else } else
sokay = NOTOKAY; sokay = NOTOKAY;
} }