test_read_format_zip_high_compression.c revision 305192
1/*- 2 * Copyright (c) 2016 Tim Kientzle 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25#include "test.h" 26__FBSDID("$FreeBSD"); 27 28#include <locale.h> 29 30 31/* 32 * Github Issue 748 reported problems with end-of-entry handling 33 * with highly-compressible data. This resulted in the end of the 34 * data being truncated (extracted as zero bytes). 35 */ 36 37/* 38 * Extract the specific test archive that was used to diagnose 39 * Issue 748: 40 */ 41DEFINE_TEST(test_read_format_zip_high_compression) 42{ 43 const char *refname = "test_read_format_zip_high_compression.zip"; 44 char *p; 45 size_t archive_size; 46 struct archive *a; 47 struct archive_entry *entry; 48 49 const void *pv; 50 size_t s; 51 int64_t o; 52 53 extract_reference_file(refname); 54 p = slurpfile(&archive_size, refname); 55 56 assert((a = archive_read_new()) != NULL); 57 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); 58 assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, archive_size, 16 * 1024)); 59 assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &entry)); 60 61 assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); 62 assertEqualInt(262144, s); 63 assertEqualInt(0, o); 64 65 assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); 66 assertEqualInt(160, s); 67 assertEqualInt(262144, o); 68 69 assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &pv, &s, &o)); 70 71 assertEqualInt(ARCHIVE_OK, archive_free(a)); 72 free(p); 73} 74 75/* 76 * Synthesize a lot of varying inputs that are highly compressible. 77 */ 78DEFINE_TEST(test_read_format_zip_high_compression2) 79{ 80 const size_t body_size = 1024 * 1024; 81 const size_t buff_size = 2 * 1024 * 1024; 82 char *body, *body_read, *buff; 83 int n; 84 85 assert((body = malloc(body_size)) != NULL); 86 assert((body_read = malloc(body_size)) != NULL); 87 assert((buff = malloc(buff_size)) != NULL); 88 89 /* Highly-compressible data: all bytes 255, except for a 90 * single 1 byte. 91 * The body is always 256k + 6 bytes long (the internal deflation 92 * buffer is exactly 256k). 93 */ 94 95 for(n = 1024; n < (int)body_size; n += 1024) { 96 struct archive *a; 97 struct archive_entry *entry; 98 size_t used = 0; 99 const void *pv; 100 size_t s; 101 int64_t o; 102 103 memset(body, 255, body_size); 104 body[n] = 1; 105 106 /* Write an archive with a single entry of n bytes. */ 107 assert((a = archive_write_new()) != NULL); 108 assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); 109 assertEqualInt(ARCHIVE_OK, archive_write_open_memory(a, buff, buff_size, &used)); 110 111 entry = archive_entry_new2(a); 112 archive_entry_set_pathname(entry, "test"); 113 archive_entry_set_filetype(entry, AE_IFREG); 114 archive_entry_set_size(entry, 262150); 115 assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); 116 archive_entry_free(entry); 117 assertEqualInt(262150, archive_write_data(a, body, 262150)); 118 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 119 120 /* Read back the entry and verify the contents. */ 121 assert((a = archive_read_new()) != NULL); 122 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 123 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 124 assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 17)); 125 assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &entry)); 126 127 assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); 128 assertEqualInt(262144, s); 129 assertEqualInt(0, o); 130 131 assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); 132 assertEqualInt(6, s); 133 assertEqualInt(262144, o); 134 135 assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &pv, &s, &o)); 136 137 assertEqualInt(ARCHIVE_OK, archive_free(a)); 138 } 139 140 free(body); 141 free(body_read); 142 free(buff); 143} 144