I recently ran into a problem with busybox tar generating archives where the size field is base-256 encoded for files larger than 8GB. Apparently this is a GNU tar extension.
Do we want to support this in pax? Below is an initial diff that at least produces the correct results when listing the archive. I have not yet verified that it gets extracted correctly. If there is interest I will do some more testing. - todd Index: bin/pax/gen_subs.c =================================================================== RCS file: /cvs/src/bin/pax/gen_subs.c,v retrieving revision 1.32 diff -u -p -u -r1.32 gen_subs.c --- bin/pax/gen_subs.c 26 Aug 2016 05:06:14 -0000 1.32 +++ bin/pax/gen_subs.c 19 Apr 2023 02:05:19 -0000 @@ -45,6 +45,7 @@ #include <unistd.h> #include <utmp.h> #include <vis.h> +#include <limits.h> #include "pax.h" #include "extern.h" @@ -279,9 +280,10 @@ ul_asc(u_long val, char *str, int len, i /* * asc_ull() - * Convert hex/octal character string into a unsigned long long. - * We do not have to check for overflow! (The headers in all - * supported formats are not large enough to create an overflow). + * Convert hex/octal/base-256 character string into a unsigned long long. + * We only have to check for overflow when parsing base-256. + * The headers in all supported formats are not large enough to create + * an overflow for hex or octal. * NOTE: strings passed to us are NOT TERMINATED. * Return: * unsigned long long value @@ -296,9 +298,9 @@ asc_ull(char *str, int len, int base) stop = str + len; /* - * skip over leading blanks and zeros + * skip over leading blanks */ - while ((str < stop) && ((*str == ' ') || (*str == '0'))) + while ((str < stop) && (*str == ' ')) ++str; /* @@ -316,7 +318,17 @@ asc_ull(char *str, int len, int base) else break; } + } else if (*str == '\200') { + /* base-256 encoding, GNU tar extension */ + while (++str < stop) { + if (tval + (unsigned char)*str > ULLONG_MAX >> 8) { + /* overflow */ + return(-1); + } + tval = (tval << 8) + (unsigned char)*str; + } } else { + /* octal */ while ((str < stop) && (*str >= '0') && (*str <= '7')) tval = (tval << 3) + (*str++ - '0'); }