test_read_truncated_filter.c revision 358088
1/*-
2 * Copyright (c) 2007-2010 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__FBSDID("$FreeBSD$");
29
30/*
31 * Check that we generate an error message when reading a truncated
32 * gzip, bzip2, compress, xz, lzma, or lzip file.
33 */
34
35static void
36test_truncation(const char *compression,
37    int (*set_compression)(struct archive *), int can_prog)
38{
39	struct archive_entry *ae;
40	struct archive* a;
41	char path[16];
42	char *buff, *data;
43	size_t buffsize, datasize, used1;
44	int i, j, r, use_prog;
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 bunch of files with semi-random data.
61	 */
62	assert((a = archive_write_new()) != NULL);
63	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
64	assertEqualIntA(a, ARCHIVE_OK,
65	    archive_write_add_filter_compress(a));
66	r = (*set_compression)(a);
67	if (r != ARCHIVE_OK && !can_prog) {
68		skipping("%s writing not supported on this platform",
69		    compression);
70		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
71		free(buff);
72		free(data);
73		return;
74	}
75	use_prog = (r == ARCHIVE_WARN && can_prog);
76	assertEqualIntA(a, ARCHIVE_OK,
77	    archive_write_set_bytes_per_block(a, 10));
78	assertEqualIntA(a, ARCHIVE_OK,
79	    archive_write_open_memory(a, buff, buffsize, &used1));
80	assert((ae = archive_entry_new()) != NULL);
81	archive_entry_set_filetype(ae, AE_IFREG);
82	archive_entry_set_size(ae, datasize);
83	for (i = 0; i < 100; i++) {
84		sprintf(path, "%s%d", compression, i);
85		archive_entry_copy_pathname(ae, path);
86		failure("%s", path);
87		if (!assertEqualIntA(a, ARCHIVE_OK,
88		    archive_write_header(a, ae))) {
89			archive_write_free(a);
90			free(data);
91			free(buff);
92			return;
93		}
94		for (j = 0; j < (int)datasize; ++j) {
95			data[j] = (char)(rand() % 256);
96		}
97		failure("%s", path);
98		if (!assertEqualIntA(a, datasize,
99		    archive_write_data(a, data, datasize))) {
100			archive_write_free(a);
101			free(data);
102			free(buff);
103			return;
104		}
105	}
106	archive_entry_free(ae);
107	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
108	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
109
110	assert((a = archive_read_new()) != NULL);
111	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
112	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
113
114	assertEqualIntA(a, ARCHIVE_OK,
115	    archive_read_open_memory(a, buff, used1 - used1/64));
116	for (i = 0; i < 100; i++) {
117		if (ARCHIVE_OK != archive_read_next_header(a, &ae)) {
118			failure("Should have non-NULL error message for %s",
119			    compression);
120			assert(NULL != archive_error_string(a));
121			break;
122		}
123		sprintf(path, "%s%d", compression, i);
124		assertEqualString(path, archive_entry_pathname(ae));
125		if (datasize != (size_t)archive_read_data(a, data, datasize)) {
126			failure("Should have non-NULL error message for %s",
127			    compression);
128			assert(NULL != archive_error_string(a));
129			break;
130		}
131	}
132	assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
133	    archive_read_close(a));
134	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
135
136	free(data);
137	free(buff);
138}
139
140DEFINE_TEST(test_read_truncated_filter_bzip2)
141{
142	test_truncation("bzip2", archive_write_add_filter_bzip2, canBzip2());
143}
144
145DEFINE_TEST(test_read_truncated_filter_compress)
146{
147	test_truncation("compress", archive_write_add_filter_compress, 0);
148}
149
150DEFINE_TEST(test_read_truncated_filter_gzip)
151{
152	test_truncation("gzip", archive_write_add_filter_gzip, canGzip());
153}
154
155DEFINE_TEST(test_read_truncated_filter_lzip)
156{
157	test_truncation("lzip", archive_write_add_filter_lzip, 0);
158}
159
160DEFINE_TEST(test_read_truncated_filter_lzma)
161{
162	test_truncation("lzma", archive_write_add_filter_lzma, 0);
163}
164
165DEFINE_TEST(test_read_truncated_filter_lzop)
166{
167	test_truncation("lzop", archive_write_add_filter_lzop, canLzop());
168}
169
170DEFINE_TEST(test_read_truncated_filter_xz)
171{
172	test_truncation("xz", archive_write_add_filter_xz, 0);
173}
174