1/*- 2 * Copyright (c) 2007 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 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "test.h" 28 29/* 30 * A basic exercise of gzip reading and writing. 31 * 32 * TODO: Add a reference file and make sure we can decompress that. 33 */ 34 35DEFINE_TEST(test_write_filter_gzip) 36{ 37 struct archive_entry *ae; 38 struct archive* a; 39 char *buff, *data; 40 size_t buffsize, datasize; 41 unsigned char *rbuff; 42 char path[16]; 43 size_t used1, used2; 44 int i, r, use_prog = 0; 45 46 buffsize = 2000000; 47 assert(NULL != (buff = (char *)malloc(buffsize))); 48 if (buff == NULL) 49 return; 50 51 datasize = 10000; 52 assert(NULL != (data = (char *)malloc(datasize))); 53 if (data == NULL) { 54 free(buff); 55 return; 56 } 57 memset(data, 0, datasize); 58 59 /* 60 * Write a 100 files and read them all back. 61 * Use default compression level (6). 62 */ 63 assert((a = archive_write_new()) != NULL); 64 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 65 r = archive_write_add_filter_gzip(a); 66 if (r != ARCHIVE_OK) { 67 if (canGzip() && r == ARCHIVE_WARN) 68 use_prog = 1; 69 else { 70 skipping("gzip writing not supported on this platform"); 71 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 72 free(buff); 73 free(data); 74 return; 75 } 76 } 77 assertEqualIntA(a, ARCHIVE_OK, 78 archive_write_set_bytes_per_block(a, 10)); 79 assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0)); 80 assertEqualString("gzip", archive_filter_name(a, 0)); 81 assertEqualIntA(a, ARCHIVE_OK, 82 archive_write_open_memory(a, buff, buffsize, &used1)); 83 assert((ae = archive_entry_new()) != NULL); 84 archive_entry_set_filetype(ae, AE_IFREG); 85 archive_entry_set_size(ae, datasize); 86 for (i = 0; i < 100; i++) { 87 snprintf(path, sizeof(path), "file%03d", i); 88 archive_entry_copy_pathname(ae, path); 89 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 90 assertA(datasize 91 == (size_t)archive_write_data(a, data, datasize)); 92 } 93 archive_entry_free(ae); 94 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 95 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 96 97 /* Basic gzip header tests */ 98 rbuff = (unsigned char *)buff; 99 assertEqualInt(rbuff[0], 0x1f); 100 assertEqualInt(rbuff[1], 0x8b); 101 assertEqualInt(rbuff[2], 0x08); 102 assertEqualInt(rbuff[3], 0x00); 103 assertEqualInt(rbuff[8], 0); /* RFC 1952 flag for compression level 6 */ 104 105 assert((a = archive_read_new()) != NULL); 106 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 107 r = archive_read_support_filter_gzip(a); 108 if (r == ARCHIVE_WARN) { 109 skipping("Can't verify gzip writing by reading back;" 110 " gzip reading not fully supported on this platform"); 111 } else { 112 assertEqualIntA(a, ARCHIVE_OK, 113 archive_read_open_memory(a, buff, used1)); 114 for (i = 0; i < 100; i++) { 115 snprintf(path, sizeof(path), "file%03d", i); 116 if (!assertEqualInt(ARCHIVE_OK, 117 archive_read_next_header(a, &ae))) 118 break; 119 assertEqualString(path, archive_entry_pathname(ae)); 120 assertEqualInt((int)datasize, archive_entry_size(ae)); 121 } 122 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 123 } 124 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 125 126 /* 127 * Repeat the cycle again, this time setting some compression 128 * options. Compression level is 9. 129 */ 130 assert((a = archive_write_new()) != NULL); 131 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 132 assertEqualIntA(a, ARCHIVE_OK, 133 archive_write_set_bytes_per_block(a, 10)); 134 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 135 archive_write_add_filter_gzip(a)); 136 assertEqualIntA(a, ARCHIVE_FAILED, 137 archive_write_set_options(a, "gzip:nonexistent-option=0")); 138 assertEqualIntA(a, ARCHIVE_OK, 139 archive_write_set_options(a, "gzip:compression-level=1")); 140 assertEqualIntA(a, ARCHIVE_OK, 141 archive_write_set_filter_option(a, NULL, "compression-level", "9")); 142 assertEqualIntA(a, ARCHIVE_FAILED, 143 archive_write_set_filter_option(a, NULL, "compression-level", "abc")); 144 assertEqualIntA(a, ARCHIVE_FAILED, 145 archive_write_set_filter_option(a, NULL, "compression-level", "99")); 146 assertEqualIntA(a, ARCHIVE_OK, 147 archive_write_set_options(a, "gzip:compression-level=9")); 148 assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); 149 for (i = 0; i < 100; i++) { 150 snprintf(path, sizeof(path), "file%03d", i); 151 assert((ae = archive_entry_new()) != NULL); 152 archive_entry_copy_pathname(ae, path); 153 archive_entry_set_size(ae, datasize); 154 archive_entry_set_filetype(ae, AE_IFREG); 155 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 156 assertA(datasize == (size_t)archive_write_data(a, data, datasize)); 157 archive_entry_free(ae); 158 } 159 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 160 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 161 162 /* Basic gzip header tests */ 163 rbuff = (unsigned char *)buff; 164 assertEqualInt(rbuff[0], 0x1f); 165 assertEqualInt(rbuff[1], 0x8b); 166 assertEqualInt(rbuff[2], 0x08); 167 assertEqualInt(rbuff[3], 0x00); 168 assertEqualInt(rbuff[8], 2); /* RFC 1952 flag for compression level 9 */ 169 170 /* Curiously, this test fails; the test data above compresses 171 * better at default compression than at level 9. */ 172 /* 173 failure("compression-level=9 wrote %d bytes, default wrote %d bytes", 174 (int)used2, (int)used1); 175 assert(used2 < used1); 176 */ 177 178 assert((a = archive_read_new()) != NULL); 179 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 180 r = archive_read_support_filter_gzip(a); 181 if (r != ARCHIVE_OK && !use_prog) { 182 skipping("gzip reading not fully supported on this platform"); 183 } else { 184 assertEqualIntA(a, ARCHIVE_OK, 185 archive_read_support_filter_all(a)); 186 assertEqualIntA(a, ARCHIVE_OK, 187 archive_read_open_memory(a, buff, used2)); 188 for (i = 0; i < 100; i++) { 189 snprintf(path, sizeof(path), "file%03d", i); 190 if (!assertEqualInt(ARCHIVE_OK, 191 archive_read_next_header(a, &ae))) 192 break; 193 assertEqualString(path, archive_entry_pathname(ae)); 194 assertEqualInt((int)datasize, archive_entry_size(ae)); 195 } 196 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 197 } 198 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 199 200 /* 201 * Repeat again, with compression level 1 202 */ 203 assert((a = archive_write_new()) != NULL); 204 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 205 assertEqualIntA(a, ARCHIVE_OK, 206 archive_write_set_bytes_per_block(a, 10)); 207 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 208 archive_write_add_filter_gzip(a)); 209 assertEqualIntA(a, ARCHIVE_OK, 210 archive_write_set_filter_option(a, NULL, "compression-level", "1")); 211 assertEqualIntA(a, ARCHIVE_OK, 212 archive_write_open_memory(a, buff, buffsize, &used2)); 213 for (i = 0; i < 100; i++) { 214 snprintf(path, sizeof(path), "file%03d", i); 215 assert((ae = archive_entry_new()) != NULL); 216 archive_entry_copy_pathname(ae, path); 217 archive_entry_set_size(ae, datasize); 218 archive_entry_set_filetype(ae, AE_IFREG); 219 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 220 failure("Writing file %s", path); 221 assertEqualIntA(a, datasize, 222 (size_t)archive_write_data(a, data, datasize)); 223 archive_entry_free(ae); 224 } 225 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 226 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 227 228 /* Level 1 really does result in larger data. */ 229 failure("Compression-level=1 wrote %d bytes; default wrote %d bytes", 230 (int)used2, (int)used1); 231 assert(used2 > used1); 232 233 /* Basic gzip header tests */ 234 rbuff = (unsigned char *)buff; 235 assertEqualInt(rbuff[0], 0x1f); 236 assertEqualInt(rbuff[1], 0x8b); 237 assertEqualInt(rbuff[2], 0x08); 238 assertEqualInt(rbuff[3], 0x00); 239 assertEqualInt(rbuff[8], 4); /* RFC 1952 flag for compression level 1 */ 240 241 assert((a = archive_read_new()) != NULL); 242 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 243 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 244 r = archive_read_support_filter_gzip(a); 245 if (r == ARCHIVE_WARN) { 246 skipping("gzip reading not fully supported on this platform"); 247 } else { 248 assertEqualIntA(a, ARCHIVE_OK, 249 archive_read_open_memory(a, buff, used2)); 250 for (i = 0; i < 100; i++) { 251 snprintf(path, sizeof(path), "file%03d", i); 252 if (!assertEqualInt(ARCHIVE_OK, 253 archive_read_next_header(a, &ae))) 254 break; 255 assertEqualString(path, archive_entry_pathname(ae)); 256 assertEqualInt((int)datasize, archive_entry_size(ae)); 257 } 258 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 259 } 260 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 261 262 /* 263 * Test various premature shutdown scenarios to make sure we 264 * don't crash or leak memory. 265 */ 266 assert((a = archive_write_new()) != NULL); 267 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 268 archive_write_add_filter_gzip(a)); 269 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 270 271 assert((a = archive_write_new()) != NULL); 272 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 273 archive_write_add_filter_gzip(a)); 274 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 275 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 276 277 assert((a = archive_write_new()) != NULL); 278 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 279 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 280 archive_write_add_filter_gzip(a)); 281 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 282 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 283 284 assert((a = archive_write_new()) != NULL); 285 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 286 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 287 archive_write_add_filter_gzip(a)); 288 assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); 289 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 290 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 291 292 /* 293 * Clean up. 294 */ 295 free(data); 296 free(buff); 297} 298