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 <tdm@cyngn.com>
Date: Thu, 11 Feb 2016 16:24:40 -0800
Subject: libtar: Cleanup, secure, and extend numeric fields
Commit: e18b457ea1cbf6be1adc3b75450ed1c737cd82ea
From: Tom Marshall <tdm@cyngn.com>
Date: Thu, 11 Feb 2016 12:49:30 -0800
Subject: libtar: Make file sizes 64-bit clean
Commit: e628c2025549a24018bc568351465130a05daafb
From: Tom Marshall <tdm@cyngn.com>
Date: Thu, 17 Apr 2014 09:39:25 -0700
Subject: libtar: Add methods for in-memory files
Commit: 8ec5627a8ff0a91724c6d5b344f0e887da922527
From: Tom Marshall <tdm@cyngn.com>
Date: Wed, 2 Jul 2014 09:34:40 -0700
Subject: libtar: Fix hardlink extract
Commit: 166d83a51e0c51abcea37694dbd7df92d03c1f56
From: philz-cwm6 <phytowardt@gmail.com>
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 <tdm@cyngn.com>
Date: Wed, 9 Apr 2014 09:35:54 -0700
Subject: libtar: Add const qualifiers to reduce compile warnings
Commit: 0600afa19fe827d06d3fcf24a7aabd52dbf487b4
Change-Id: I6d008cb6fdf950f835bbed63aeb8727cc5c86083
diff --git a/libtar/util.c b/libtar/util.c
index 31e8315..f472f38 100644
--- a/libtar/util.c
+++ b/libtar/util.c
@@ -126,7 +126,6 @@
return sum;
}
-
/* calculate a signed header checksum */
int
th_signed_crc_calc(TAR *t)
@@ -141,25 +140,73 @@
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];
- sscanf(oct, "%o", &i);
-
- return i;
+ memcpy(tmp, oct, octlen);
+ tmp[octlen] = '\0';
+ return sscanf(oct, "%llo", &val) == 1 ? (int64_t)val : 0;
}
-/* integer to string-octal conversion, no NULL */
+/* 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 NULL-terminated string-octal conversion */
+void int_to_oct(int64_t num, char *oct, size_t octlen)
+{
+ 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_nonull(int num, char *oct, size_t octlen)
+int_to_oct_ex(int64_t num, char *oct, size_t octlen)
{
- snprintf(oct, octlen, "%*lo", octlen - 1, (unsigned long)num);
- oct[octlen - 1] = ' ';
+ 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);
}
-
-