From cc20f90507adb74578f509c7ff7b622d6058f7aa Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Sun, 29 Nov 2020 14:03:30 -0500 Subject: [PATCH] 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. --- src/arscan.c | 37 ++++++++++++++++++++++++++++++++----- 1 file 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,