]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
hexdump: do not use atoi()
authorKarel Zak <kzak@redhat.com>
Fri, 25 Jun 2021 09:05:21 +0000 (11:05 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 20 Jul 2021 09:51:44 +0000 (11:51 +0200)
Addresses: https://github.com/karelzak/util-linux/issues/1358
Signed-off-by: Karel Zak <kzak@redhat.com>
text-utils/hexdump-parse.c

index 0b460a70d03e029fdda79d52c708b1a6c6deb93d..1d2e689b679ddddd28e6a62365574a2cb63d3818 100644 (file)
@@ -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;
                        }