diff options
Diffstat (limited to 'archival')
-rw-r--r-- | archival/Config.in | 9 | ||||
-rw-r--r-- | archival/libunarchive/get_header_cpio.c | 3 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 29 |
3 files changed, 35 insertions, 6 deletions
diff --git a/archival/Config.in b/archival/Config.in index 661c71ccf..49070da06 100644 --- a/archival/Config.in +++ b/archival/Config.in | |||
@@ -205,6 +205,15 @@ config FEATURE_TAR_OLDGNU_COMPATIBILITY | |||
205 | the old GNU format; help to kill this old format by | 205 | the old GNU format; help to kill this old format by |
206 | repacking your ancient archives with the new format. | 206 | repacking your ancient archives with the new format. |
207 | 207 | ||
208 | config FEATURE_TAR_OLDSUN_COMPATIBILITY | ||
209 | bool "Enable untarring of tarballs with checksums produced by buggy Sun tar" | ||
210 | default N | ||
211 | depends on TAR | ||
212 | help | ||
213 | This option is required to unpack archives created by some old | ||
214 | version of Sun's tar (it was calculating checksum using signed arithmetic). | ||
215 | It is said to be fixed in newer Sun tar, but "old" tarballs still exist. | ||
216 | |||
208 | config FEATURE_TAR_GNU_EXTENSIONS | 217 | config FEATURE_TAR_GNU_EXTENSIONS |
209 | bool "Enable support for some GNU tar extensions" | 218 | bool "Enable support for some GNU tar extensions" |
210 | default y | 219 | default y |
diff --git a/archival/libunarchive/get_header_cpio.c b/archival/libunarchive/get_header_cpio.c index 724368be2..3f5135512 100644 --- a/archival/libunarchive/get_header_cpio.c +++ b/archival/libunarchive/get_header_cpio.c | |||
@@ -16,8 +16,9 @@ typedef struct hardlinks_s { | |||
16 | char get_header_cpio(archive_handle_t *archive_handle) | 16 | char get_header_cpio(archive_handle_t *archive_handle) |
17 | { | 17 | { |
18 | static hardlinks_t *saved_hardlinks = NULL; | 18 | static hardlinks_t *saved_hardlinks = NULL; |
19 | static unsigned short pending_hardlinks = 0; | 19 | static unsigned pending_hardlinks = 0; |
20 | static int inode; | 20 | static int inode; |
21 | |||
21 | file_header_t *file_header = archive_handle->file_header; | 22 | file_header_t *file_header = archive_handle->file_header; |
22 | char cpio_header[110]; | 23 | char cpio_header[110]; |
23 | int namesize; | 24 | int namesize; |
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index d42f4c276..1a7a687cf 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
@@ -36,7 +36,7 @@ static unsigned long long getOctal(char *str, int len) | |||
36 | */ | 36 | */ |
37 | str[len] = '\0'; | 37 | str[len] = '\0'; |
38 | v = strtoull(str, &str, 8); | 38 | v = strtoull(str, &str, 8); |
39 | if (*str) | 39 | if (*str && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY || *str != ' ')) |
40 | bb_error_msg_and_die("corrupted octal value in tar header"); | 40 | bb_error_msg_and_die("corrupted octal value in tar header"); |
41 | return v; | 41 | return v; |
42 | } | 42 | } |
@@ -45,7 +45,7 @@ static unsigned long long getOctal(char *str, int len) | |||
45 | void BUG_tar_header_size(void); | 45 | void BUG_tar_header_size(void); |
46 | char get_header_tar(archive_handle_t *archive_handle) | 46 | char get_header_tar(archive_handle_t *archive_handle) |
47 | { | 47 | { |
48 | static int end; | 48 | static smallint end; |
49 | 49 | ||
50 | file_header_t *file_header = archive_handle->file_header; | 50 | file_header_t *file_header = archive_handle->file_header; |
51 | struct { | 51 | struct { |
@@ -69,7 +69,10 @@ char get_header_tar(archive_handle_t *archive_handle) | |||
69 | char padding[12]; /* 500-512 */ | 69 | char padding[12]; /* 500-512 */ |
70 | } tar; | 70 | } tar; |
71 | char *cp; | 71 | char *cp; |
72 | int i, sum_u, sum_s, sum; | 72 | int i, sum_u, sum; |
73 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | ||
74 | int sum_s; | ||
75 | #endif | ||
73 | int parse_names; | 76 | int parse_names; |
74 | 77 | ||
75 | if (sizeof(tar) != 512) | 78 | if (sizeof(tar) != 512) |
@@ -115,20 +118,36 @@ char get_header_tar(archive_handle_t *archive_handle) | |||
115 | * POSIX says that checksum is done on unsigned bytes, but | 118 | * POSIX says that checksum is done on unsigned bytes, but |
116 | * Sun and HP-UX gets it wrong... more details in | 119 | * Sun and HP-UX gets it wrong... more details in |
117 | * GNU tar source. */ | 120 | * GNU tar source. */ |
118 | sum_s = sum_u = ' ' * sizeof(tar.chksum); | 121 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY |
122 | sum_s = ' ' * sizeof(tar.chksum); | ||
123 | #endif | ||
124 | sum_u = ' ' * sizeof(tar.chksum); | ||
119 | for (i = 0; i < 148 ; i++) { | 125 | for (i = 0; i < 148 ; i++) { |
120 | sum_u += ((unsigned char*)&tar)[i]; | 126 | sum_u += ((unsigned char*)&tar)[i]; |
127 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | ||
121 | sum_s += ((signed char*)&tar)[i]; | 128 | sum_s += ((signed char*)&tar)[i]; |
129 | #endif | ||
122 | } | 130 | } |
123 | for (i = 156; i < 512 ; i++) { | 131 | for (i = 156; i < 512 ; i++) { |
124 | sum_u += ((unsigned char*)&tar)[i]; | 132 | sum_u += ((unsigned char*)&tar)[i]; |
133 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | ||
125 | sum_s += ((signed char*)&tar)[i]; | 134 | sum_s += ((signed char*)&tar)[i]; |
135 | #endif | ||
136 | } | ||
137 | #if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY | ||
138 | sum = strtoul(tar.chksum, &cp, 8); | ||
139 | if ((*cp && *cp != ' ') | ||
140 | || (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) | ||
141 | ) { | ||
142 | bb_error_msg_and_die("invalid tar header checksum"); | ||
126 | } | 143 | } |
144 | #else | ||
127 | /* This field does not need special treatment (getOctal) */ | 145 | /* This field does not need special treatment (getOctal) */ |
128 | sum = xstrtoul(tar.chksum, 8); | 146 | sum = xstrtoul(tar.chksum, 8); |
129 | if (sum_u != sum && sum_s != sum) { | 147 | if (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) { |
130 | bb_error_msg_and_die("invalid tar header checksum"); | 148 | bb_error_msg_and_die("invalid tar header checksum"); |
131 | } | 149 | } |
150 | #endif | ||
132 | 151 | ||
133 | /* 0 is reserved for high perf file, treat as normal file */ | 152 | /* 0 is reserved for high perf file, treat as normal file */ |
134 | if (!tar.typeflag) tar.typeflag = '0'; | 153 | if (!tar.typeflag) tar.typeflag = '0'; |