Skip to content

Commit 927ded6

Browse files
committed
Fix issue when skipping first file in 7zip archive that is a multiple of 65536 bytes
1 parent 13c710a commit 927ded6

4 files changed

+59
-1
lines changed

Diff for: Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ libarchive_test_EXTRA_DIST=\
789789
libarchive/test/test_read_format_7zip_encryption.7z.uu \
790790
libarchive/test/test_read_format_7zip_encryption_header.7z.uu \
791791
libarchive/test/test_read_format_7zip_encryption_partially.7z.uu \
792+
libarchive/test/test_read_format_7zip_extract_second.7z.uu \
792793
libarchive/test/test_read_format_7zip_lzma1.7z.uu \
793794
libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \
794795
libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \

Diff for: libarchive/archive_read_support_format_7zip.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -3462,7 +3462,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
34623462
/*
34633463
* Skip the bytes we already has skipped in skip_stream().
34643464
*/
3465-
while (skip_bytes) {
3465+
while (1) {
34663466
ssize_t skipped;
34673467

34683468
if (zip->uncompressed_buffer_bytes_remaining == 0) {
@@ -3482,6 +3482,10 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
34823482
return (ARCHIVE_FATAL);
34833483
}
34843484
}
3485+
3486+
if (!skip_bytes)
3487+
break;
3488+
34853489
skipped = get_uncompressed_data(
34863490
a, buff, (size_t)skip_bytes, 0);
34873491
if (skipped < 0)

Diff for: libarchive/test/test_read_format_7zip.c

+42
Original file line numberDiff line numberDiff line change
@@ -1257,5 +1257,47 @@ DEFINE_TEST(test_read_format_7zip_win_attrib)
12571257
assertEqualString("system", archive_entry_fflags_text(ae));
12581258

12591259

1260+
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1261+
}
1262+
1263+
DEFINE_TEST(test_read_format_7zip_extract_second)
1264+
{
1265+
struct archive *a;
1266+
char buffer[256];
1267+
1268+
assert((a = archive_read_new()) != NULL);
1269+
1270+
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
1271+
skipping(
1272+
"7zip:lzma decoding is not supported on this platform");
1273+
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1274+
return;
1275+
}
1276+
1277+
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
1278+
1279+
/*
1280+
* The test archive has two files: first.txt which is a 65,536 file (the
1281+
* size of the uncompressed buffer), and second.txt which has contents
1282+
* we will validate. This test ensures we can skip first.txt and still
1283+
* be able to read the contents of second.txt
1284+
*/
1285+
const char *refname = "test_read_format_7zip_extract_second.7z";
1286+
extract_reference_file(refname);
1287+
1288+
assertEqualIntA(a, ARCHIVE_OK,
1289+
archive_read_open_filename(a, refname, 10240));
1290+
1291+
struct archive_entry *ae;
1292+
1293+
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
1294+
assertEqualString("first.txt", archive_entry_pathname(ae));
1295+
1296+
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
1297+
assertEqualString("second.txt", archive_entry_pathname(ae));
1298+
1299+
assertEqualInt(23, archive_read_data(a, buffer, sizeof(buffer)));
1300+
assertEqualMem("This is from second.txt", buffer, 23);
1301+
12601302
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
12611303
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
begin 644 test_read_format_7zip_extract_second.7z
2+
M-WJ\KR<<``-N%=VX!@$````````B`````````*R\U.<`&`Q"DFIGO`[1,RO\
3+
MN,RA7-QU1L&_]O_/$0MMLIEBUR3'BDX@M2C-5'VG./-4,5@W3Q@*__^7_,[H
4+
MEO`DB'[ZI>@H2_E>/W.2G$$.P01-X!YN5";SS[3#7Z4Q1G/EF.0'^D*[S8&8
5+
M[FV9DYX7,SA%^.Q\'?__P!@`````@3,'K@_4WV/Q0A7VLXG$X?GH4=5W^`UM
6+
M$N_EX$)LE*?K$W5?WLP:X0T[Q%V^?A!0E\VZRBB,)(MO`C`LO[O!3(1YL)<:
7+
MJ."`';WU;>GP5',%Z=6?*/H9*Z)&\*!2^<F\P&>,RV`R30UOBH8+5.;;2IKF
8+
M0W://&'?"L?0L2!)`*]F30B0&/_'<4``%P9Z`0F`C``'"P$``2,#`0$%70``
9+
-@``,@*@*`6]FB2D`````
10+
`
11+
end

0 commit comments

Comments
 (0)