diff options
author | Paul Smith <psmith@gnu.org> | 2020-11-29 14:03:30 -0500 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2020-11-29 17:59:40 -0500 |
commit | cc20f90507adb74578f509c7ff7b622d6058f7aa (patch) | |
tree | 5626d7d93ad8d9318f1d90901cc5e79c4e215d88 /src/arscan.c | |
parent | 9e2fa24649b870d79e2582f46e851fb34daa4762 (diff) | |
download | make-git-cc20f90507adb74578f509c7ff7b622d6058f7aa.tar.gz |
Avoid some valgrind warnings
Using sscanf() to parse archive header values (struct ar_hdr) can lead
to valgrind warnings which are probably bogus but are annoying.
To be safer, create a local method to convert the ASCII integer
strings into integers.
* src/arscan.c (parse_int): Turn integer strings into integers.
(ar_scan): Initialize struct ar_hdr memory.
Call parse_int() rather than sscanf/atol.
Diffstat (limited to 'src/arscan.c')
-rw-r--r-- | src/arscan.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/arscan.c b/src/arscan.c index 3ce21db8..2565fbbb 100644 --- a/src/arscan.c +++ b/src/arscan.c @@ -378,6 +378,31 @@ struct ar_hdr #include "output.h" + +static unsigned long int +parse_int (const char *ptr, const size_t len, const int base, + const char *type, const char *archive, const char *name) +{ + const char *const ep = ptr + len; + const char max = '0' + base - 1; + long int val = 0; + + /* In all the versions I know of the spaces come last, but be safe. */ + while (ptr < ep && *ptr == ' ') + ++ptr; + + while (ptr < ep && *ptr != ' ') + { + if (*ptr < '0' || *ptr > max) + OSSS (fatal, NILF, _("Invalid %s for archive %s member %s"), + type, archive, name); + val = (val * base) + (*ptr - '0'); + ++ptr; + } + + return val; +} + /* Takes three arguments ARCHIVE, FUNCTION and ARG. Open the archive named ARCHIVE, find its members one by one, @@ -540,6 +565,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) long int fnval; off_t o; + memset(&member_header, '\0', sizeof (member_header)); + EINTRLOOP (o, lseek (desc, member_offset, 0)); if (o < 0) goto invalid; @@ -703,8 +730,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) } #ifndef M_XENIX - sscanf (TOCHAR (member_header.ar_mode), "%8o", &eltmode); - eltsize = atol (TOCHAR (member_header.ar_size)); + eltmode = parse_int (TOCHAR (member_header.ar_mode), sizeof (member_header.ar_mode), 8, "mode", archive, name); + eltsize = parse_int (TOCHAR (member_header.ar_size), sizeof (member_header.ar_size), 10, "size", archive, name); #else /* Xenix. */ eltmode = (unsigned short int) member_header.ar_mode; eltsize = member_header.ar_size; @@ -714,9 +741,9 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) (*function) (desc, name, ! long_name, member_offset, member_offset + AR_HDR_SIZE, eltsize, #ifndef M_XENIX - atol (TOCHAR (member_header.ar_date)), - atoi (TOCHAR (member_header.ar_uid)), - atoi (TOCHAR (member_header.ar_gid)), + parse_int (TOCHAR (member_header.ar_date), sizeof (member_header.ar_date), 10, "date", archive, name), + parse_int (TOCHAR (member_header.ar_uid), sizeof (member_header.ar_uid), 10, "uid", archive, name), + parse_int (TOCHAR (member_header.ar_gid), sizeof (member_header.ar_gid), 10, "gid", archive, name), #else /* Xenix. */ member_header.ar_date, member_header.ar_uid, |