From 6f57f7c60167b11e0e7769310aa8878d2980a3da Mon Sep 17 00:00:00 2001 From: James Christopher Adduono Date: Tue, 1 Mar 2016 16:01:53 -0500 Subject: Merge code from upstream libtar + bug fixes All updates and fixes applied from upstream libtar as of March 1, 2016. Debug flag is disabled, however non-debug output now provides 1 line of useful output per object extracted. I've also merged some fixes from CyanogenMod's fork of libtar: From: Tom Marshall Date: Thu, 11 Feb 2016 16:24:40 -0800 Subject: libtar: Cleanup, secure, and extend numeric fields Commit: e18b457ea1cbf6be1adc3b75450ed1c737cd82ea From: Tom Marshall Date: Thu, 11 Feb 2016 12:49:30 -0800 Subject: libtar: Make file sizes 64-bit clean Commit: e628c2025549a24018bc568351465130a05daafb From: Tom Marshall Date: Thu, 17 Apr 2014 09:39:25 -0700 Subject: libtar: Add methods for in-memory files Commit: 8ec5627a8ff0a91724c6d5b344f0e887da922527 From: Tom Marshall Date: Wed, 2 Jul 2014 09:34:40 -0700 Subject: libtar: Fix hardlink extract Commit: 166d83a51e0c51abcea37694dbd7df92d03c1f56 From: philz-cwm6 Date: Sat, 26 Apr 2014 01:11:35 +0200 Subject: libtar: Various bug fixes and enhancements Commit: a271d763e94235ccee9ecaabdb52bf4b9b2f8c06 (Some of this was not merged in, as better solutions were available from upstream libtar) From: Tom Marshall Date: Wed, 9 Apr 2014 09:35:54 -0700 Subject: libtar: Add const qualifiers to reduce compile warnings Commit: 0600afa19fe827d06d3fcf24a7aabd52dbf487b4 Change-Id: I6d008cb6fdf950f835bbed63aeb8727cc5c86083 --- libtar/util.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 12 deletions(-) (limited to 'libtar/util.c') diff --git a/libtar/util.c b/libtar/util.c index 31e831507..f472f38b5 100644 --- a/libtar/util.c +++ b/libtar/util.c @@ -126,7 +126,6 @@ th_crc_calc(TAR *t) return sum; } - /* calculate a signed header checksum */ int th_signed_crc_calc(TAR *t) @@ -141,25 +140,73 @@ th_signed_crc_calc(TAR *t) return sum; } - /* string-octal to integer conversion */ -int -oct_to_int(char *oct) +int64_t +oct_to_int(char *oct, size_t octlen) { - int i; + long long int val; + char tmp[octlen + 1]; + + memcpy(tmp, oct, octlen); + tmp[octlen] = '\0'; + return sscanf(oct, "%llo", &val) == 1 ? (int64_t)val : 0; +} - sscanf(oct, "%o", &i); - return i; +/* string-octal or binary to integer conversion */ +int64_t oct_to_int_ex(char *oct, size_t octlen) +{ + if (*(unsigned char *)oct & 0x80) { + int64_t val = 0; + char tmp[octlen]; + unsigned char *p; + unsigned int i; + + memcpy(tmp, oct, octlen); + *tmp &= 0x7f; + p = (unsigned char *)tmp + octlen - sizeof(val); + for (i = 0; i < sizeof(val); ++i) { + val <<= 8; + val |= *(p++); + } + return val; + } + return oct_to_int(oct, octlen); } -/* integer to string-octal conversion, no NULL */ -void -int_to_oct_nonull(int num, char *oct, size_t octlen) +/* integer to NULL-terminated string-octal conversion */ +void int_to_oct(int64_t num, char *oct, size_t octlen) { - snprintf(oct, octlen, "%*lo", octlen - 1, (unsigned long)num); - oct[octlen - 1] = ' '; + char tmp[sizeof(num)*3 + 1]; + int olen; + + olen = sprintf(tmp, "%0*llo", (int)octlen, (long long)num); + memcpy(oct, tmp + olen - octlen + 1, octlen); } +/* integer to string-octal conversion, or binary as necessary */ +void +int_to_oct_ex(int64_t num, char *oct, size_t octlen) +{ + if (num < 0 || num >= ((int64_t)1 << ((octlen - 1) * 3))) { + unsigned char *p; + unsigned int i; + + memset(oct, 0, octlen); + p = (unsigned char *)oct + octlen; + for (i = 0; i < sizeof(num); ++i) { + *(--p) = num & 0xff; + num >>= 8; + } + if (num < 0) { + for (; i < octlen; ++i) { + *(--p) = 0xff; + } + } + *(unsigned char *)oct |= 0x80; + return; + } + int_to_oct(num, oct, octlen); +} -- cgit v1.2.3