svn commit: trunk/busybox/archival: libunarchive

vda at busybox.net vda at busybox.net
Sat Mar 3 20:06:59 UTC 2007


Author: vda
Date: 2007-03-03 12:06:59 -0800 (Sat, 03 Mar 2007)
New Revision: 18001

Log:
tar: handle tarfiles with (broken) checksums a-la Sun.


Modified:
   trunk/busybox/archival/libunarchive/get_header_tar.c
   trunk/busybox/archival/tar.c


Changeset:
Modified: trunk/busybox/archival/libunarchive/get_header_tar.c
===================================================================
--- trunk/busybox/archival/libunarchive/get_header_tar.c	2007-03-03 02:20:17 UTC (rev 18000)
+++ trunk/busybox/archival/libunarchive/get_header_tar.c	2007-03-03 20:06:59 UTC (rev 18001)
@@ -69,7 +69,7 @@
 		char padding[12];   /* 500-512 */
 	} tar;
 	char *cp;
-	int sum, i;
+	int i, sum_u, sum_s, sum;
 	int parse_names;
 
 	if (sizeof(tar) != 512)
@@ -110,16 +110,23 @@
 #endif
 			bb_error_msg_and_die("invalid tar magic");
 	}
-	/* Do checksum on headers */
-	sum = ' ' * sizeof(tar.chksum);
+
+	/* Do checksum on headers.
+	 * POSIX says that checksum is done on unsigned bytes, but
+	 * Sun and HP-UX fucked it up... more details in
+	 * GNU tar source. */
+	sum_s = sum_u = ' ' * sizeof(tar.chksum);
 	for (i = 0; i < 148 ; i++) {
-		sum += ((char*)&tar)[i];
+		sum_u += ((unsigned char*)&tar)[i];
+		sum_s += ((signed char*)&tar)[i];
 	}
 	for (i = 156; i < 512 ; i++) {
-		sum += ((char*)&tar)[i];
+		sum_u += ((unsigned char*)&tar)[i];
+		sum_s += ((signed char*)&tar)[i];
 	}
 	/* This field does not need special treatment (getOctal) */
-	if (sum != xstrtoul(tar.chksum, 8)) {
+	sum = xstrtoul(tar.chksum, 8);
+	if (sum_u != sum && sum_s != sum) {
 		bb_error_msg_and_die("invalid tar header checksum");
 	}
 

Modified: trunk/busybox/archival/tar.c
===================================================================
--- trunk/busybox/archival/tar.c	2007-03-03 02:20:17 UTC (rev 18000)
+++ trunk/busybox/archival/tar.c	2007-03-03 20:06:59 UTC (rev 18001)
@@ -173,6 +173,9 @@
 
 static void chksum_and_xwrite(int fd, struct TarHeader* hp)
 {
+	/* POSIX says that checksum is done on unsigned bytes
+	 * (Sun and HP-UX fucked it up... more details in
+	 * GNU tar source) */
 	const unsigned char *cp;
 	int chksum, size;
 




More information about the busybox-cvs mailing list