Line data Source code
1 : /*
2 : Zipios -- a small C++ library that provides easy access to .zip files.
3 :
4 : Copyright (C) 2000-2007 Thomas Sondergaard
5 : Copyright (C) 2015-2019 Made to Order Software Corporation
6 :
7 : This library is free software; you can redistribute it and/or
8 : modify it under the terms of the GNU Lesser General Public
9 : License as published by the Free Software Foundation; either
10 : version 2.1 of the License, or (at your option) any later version.
11 :
12 : This library is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : Lesser General Public License for more details.
16 :
17 : You should have received a copy of the GNU Lesser General Public
18 : License along with this library; if not, write to the Free Software
19 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 : */
21 :
22 : /** \file
23 : *
24 : * Zipios unit tests for the DirectoryEntry class.
25 : */
26 :
27 : #include "tests.hpp"
28 :
29 : #include "zipios/directoryentry.hpp"
30 : #include "zipios/zipiosexceptions.hpp"
31 : #include "zipios/dosdatetime.hpp"
32 :
33 : #include <fstream>
34 :
35 : #include <sys/stat.h>
36 : #include <unistd.h>
37 :
38 :
39 : /** \brief Local definitions used globally in the DirectoryEntry tests.
40 : *
41 : */
42 : namespace
43 : {
44 :
45 :
46 : /** \brief Expected level defined as a variable.
47 : *
48 : * This definition is used because otherwise catch fails seeing the
49 : * definition as a global and the linkage fails.
50 : */
51 : zipios::FileEntry::CompressionLevel const g_expected_level(zipios::FileEntry::COMPRESSION_LEVEL_DEFAULT);
52 :
53 : /** \brief Directories make use of level 'none'.
54 : *
55 : * This value is to verify that the compression level of a directory
56 : * is properly defined.
57 : */
58 : zipios::FileEntry::CompressionLevel const g_directory_level(zipios::FileEntry::COMPRESSION_LEVEL_NONE);
59 :
60 :
61 : } // no name namespace
62 :
63 :
64 13 : SCENARIO("DirectoryEntry with invalid paths", "[DirectoryEntry] [FileEntry]")
65 : {
66 24 : GIVEN("test a fantom file (path that \"cannot\" exists) and no comment")
67 : {
68 24 : zipios::DirectoryEntry de(zipios::FilePath("/this/file/really/should/not/exist/period.txt"), "");
69 :
70 : // first, check that the object is setup as expected
71 24 : SECTION("verify that the object looks as expected")
72 : {
73 1 : REQUIRE(de.isEqual(de));
74 1 : REQUIRE(de.getComment().empty());
75 1 : REQUIRE(de.getCompressedSize() == 0);
76 1 : REQUIRE(de.getCrc() == 0);
77 1 : REQUIRE(de.getEntryOffset() == 0);
78 1 : REQUIRE(de.getExtra().empty());
79 1 : REQUIRE(de.getHeaderSize() == 0);
80 1 : REQUIRE(de.getLevel() == g_expected_level);
81 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
82 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
83 1 : REQUIRE(de.getFileName() == "period.txt");
84 1 : REQUIRE(de.getSize() == 0);
85 1 : REQUIRE(de.getTime() == 0); // invalid date
86 1 : REQUIRE(de.getUnixTime() == 0);
87 1 : REQUIRE_FALSE(de.hasCrc());
88 1 : REQUIRE_FALSE(de.isDirectory());
89 1 : REQUIRE_FALSE(de.isValid());
90 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
91 :
92 1 : REQUIRE_THROWS_AS(de.read(std::cin), zipios::IOException);
93 1 : REQUIRE_THROWS_AS(de.write(std::cout), zipios::IOException);
94 :
95 2 : zipios::FileEntry::pointer_t null_entry;
96 : // REQUIRE_FALSE(de.isEqual(*null_entry)); // here we are passing a NULL reference which most people think is something impossible to do...
97 : //REQUIRE_FALSE(null_entry->isEqual(de)); -- that would obviously crash!
98 :
99 2 : zipios::DirectoryEntry empty(zipios::FilePath(""), "");
100 1 : REQUIRE_FALSE(de.isEqual(empty));
101 1 : REQUIRE_FALSE(empty.isEqual(de));
102 :
103 : // attempt a clone now, should have the same content
104 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
105 :
106 1 : REQUIRE(clone->getComment().empty());
107 1 : REQUIRE(clone->getCompressedSize() == 0);
108 1 : REQUIRE(clone->getCrc() == 0);
109 1 : REQUIRE(clone->getEntryOffset() == 0);
110 1 : REQUIRE(clone->getExtra().empty());
111 1 : REQUIRE(clone->getHeaderSize() == 0);
112 1 : REQUIRE(clone->getLevel() == g_expected_level);
113 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
114 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
115 1 : REQUIRE(clone->getFileName() == "period.txt");
116 1 : REQUIRE(clone->getSize() == 0);
117 1 : REQUIRE(clone->getTime() == 0); // invalid date
118 1 : REQUIRE(clone->getUnixTime() == 0);
119 1 : REQUIRE_FALSE(clone->hasCrc());
120 1 : REQUIRE_FALSE(clone->isDirectory());
121 1 : REQUIRE_FALSE(clone->isValid());
122 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
123 1 : REQUIRE(clone->isEqual(de));
124 1 : REQUIRE(de.isEqual(*clone));
125 : }
126 :
127 24 : WHEN("setting the comment")
128 : {
129 1 : de.setComment("new comment");
130 :
131 2 : THEN("we can read it and nothing else changed")
132 : {
133 1 : REQUIRE(de.getComment() == "new comment");
134 1 : REQUIRE(de.getCompressedSize() == 0);
135 1 : REQUIRE(de.getCrc() == 0);
136 1 : REQUIRE(de.getEntryOffset() == 0);
137 1 : REQUIRE(de.getExtra().empty());
138 1 : REQUIRE(de.getHeaderSize() == 0);
139 1 : REQUIRE(de.getLevel() == g_expected_level);
140 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
141 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
142 1 : REQUIRE(de.getFileName() == "period.txt");
143 1 : REQUIRE(de.getSize() == 0);
144 1 : REQUIRE(de.getTime() == 0); // invalid date
145 1 : REQUIRE(de.getUnixTime() == 0);
146 1 : REQUIRE_FALSE(de.hasCrc());
147 1 : REQUIRE_FALSE(de.isDirectory());
148 1 : REQUIRE_FALSE(de.isValid());
149 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
150 :
151 2 : zipios::DirectoryEntry other(zipios::FilePath("another/path"), "");
152 1 : REQUIRE_FALSE(de.isEqual(other));
153 1 : REQUIRE_FALSE(other.isEqual(de));
154 :
155 : // attempt a clone now, should have the same content
156 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
157 :
158 1 : REQUIRE(clone->getComment() == "new comment");
159 1 : REQUIRE(clone->getCompressedSize() == 0);
160 1 : REQUIRE(clone->getCrc() == 0);
161 1 : REQUIRE(clone->getEntryOffset() == 0);
162 1 : REQUIRE(clone->getExtra().empty());
163 1 : REQUIRE(clone->getHeaderSize() == 0);
164 1 : REQUIRE(clone->getLevel() == g_expected_level);
165 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
166 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
167 1 : REQUIRE(clone->getFileName() == "period.txt");
168 1 : REQUIRE(clone->getSize() == 0);
169 1 : REQUIRE(clone->getTime() == 0); // invalid date
170 1 : REQUIRE(clone->getUnixTime() == 0);
171 1 : REQUIRE_FALSE(clone->hasCrc());
172 1 : REQUIRE_FALSE(clone->isDirectory());
173 1 : REQUIRE_FALSE(clone->isValid());
174 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
175 1 : REQUIRE(clone->isEqual(de));
176 1 : REQUIRE(de.isEqual(*clone));
177 : }
178 : }
179 :
180 24 : WHEN("setting the compressed size")
181 : {
182 : // zero would not really prove anything so skip such
183 : // (although it may be extremely rare...)
184 : size_t r;
185 0 : do
186 : {
187 1 : r = zipios_test::rand_size_t();
188 : }
189 1 : while(r == 0);
190 1 : de.setCompressedSize(r);
191 :
192 2 : THEN("we ignore it")
193 : {
194 1 : REQUIRE(de.getComment().empty());
195 1 : REQUIRE(de.getCompressedSize() == 0);
196 1 : REQUIRE(de.getCrc() == 0);
197 1 : REQUIRE(de.getEntryOffset() == 0);
198 1 : REQUIRE(de.getExtra().empty());
199 1 : REQUIRE(de.getHeaderSize() == 0);
200 1 : REQUIRE(de.getLevel() == g_expected_level);
201 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
202 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
203 1 : REQUIRE(de.getFileName() == "period.txt");
204 1 : REQUIRE(de.getSize() == 0);
205 1 : REQUIRE(de.getTime() == 0); // invalid date
206 1 : REQUIRE(de.getUnixTime() == 0);
207 1 : REQUIRE_FALSE(de.hasCrc());
208 1 : REQUIRE_FALSE(de.isDirectory());
209 1 : REQUIRE_FALSE(de.isValid());
210 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
211 :
212 2 : zipios::DirectoryEntry same(zipios::FilePath("/this/file/really/should/not/exist/period.txt"), "");
213 1 : REQUIRE(de.isEqual(same));
214 1 : REQUIRE(same.isEqual(de));
215 :
216 2 : zipios::DirectoryEntry other(zipios::FilePath("this/file/really/should/not/exist/period.txt"), "");
217 1 : REQUIRE_FALSE(de.isEqual(other));
218 1 : REQUIRE_FALSE(other.isEqual(de));
219 :
220 : // attempt a clone now, should have the same content
221 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
222 :
223 1 : REQUIRE(clone->getComment().empty());
224 1 : REQUIRE(clone->getCompressedSize() == 0);
225 1 : REQUIRE(clone->getCrc() == 0);
226 1 : REQUIRE(clone->getEntryOffset() == 0);
227 1 : REQUIRE(clone->getExtra().empty());
228 1 : REQUIRE(clone->getHeaderSize() == 0);
229 1 : REQUIRE(clone->getLevel() == g_expected_level);
230 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
231 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
232 1 : REQUIRE(clone->getFileName() == "period.txt");
233 1 : REQUIRE(clone->getSize() == 0);
234 1 : REQUIRE(clone->getTime() == 0); // invalid date
235 1 : REQUIRE(clone->getUnixTime() == 0);
236 1 : REQUIRE_FALSE(clone->hasCrc());
237 1 : REQUIRE_FALSE(clone->isDirectory());
238 1 : REQUIRE_FALSE(clone->isValid());
239 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
240 1 : REQUIRE(clone->isEqual(de));
241 1 : REQUIRE(de.isEqual(*clone));
242 : }
243 : }
244 :
245 24 : WHEN("setting the CRC")
246 : {
247 : // zero would not really prove anything so skip such
248 : uint32_t r;
249 0 : do
250 : {
251 1 : r = rand();
252 : }
253 1 : while(r == 0);
254 1 : de.setCrc(rand());
255 :
256 2 : THEN("we ignore it")
257 : {
258 1 : REQUIRE(de.getComment().empty());
259 1 : REQUIRE(de.getCompressedSize() == 0);
260 1 : REQUIRE(de.getCrc() == 0);
261 1 : REQUIRE(de.getEntryOffset() == 0);
262 1 : REQUIRE(de.getExtra().empty());
263 1 : REQUIRE(de.getHeaderSize() == 0);
264 1 : REQUIRE(de.getLevel() == g_expected_level);
265 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
266 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
267 1 : REQUIRE(de.getFileName() == "period.txt");
268 1 : REQUIRE(de.getSize() == 0);
269 1 : REQUIRE(de.getTime() == 0); // invalid date
270 1 : REQUIRE(de.getUnixTime() == 0);
271 1 : REQUIRE_FALSE(de.hasCrc());
272 1 : REQUIRE_FALSE(de.isDirectory());
273 1 : REQUIRE_FALSE(de.isValid());
274 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
275 :
276 2 : zipios::DirectoryEntry other(zipios::FilePath("/this/file/really/should/not/exist/period"), "");
277 1 : REQUIRE_FALSE(de.isEqual(other));
278 1 : REQUIRE_FALSE(other.isEqual(de));
279 :
280 : // attempt a clone now, should have the same content
281 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
282 :
283 1 : REQUIRE(clone->getComment().empty());
284 1 : REQUIRE(clone->getCompressedSize() == 0);
285 1 : REQUIRE(clone->getCrc() == 0);
286 1 : REQUIRE(clone->getEntryOffset() == 0);
287 1 : REQUIRE(clone->getExtra().empty());
288 1 : REQUIRE(clone->getHeaderSize() == 0);
289 1 : REQUIRE(clone->getLevel() == g_expected_level);
290 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
291 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
292 1 : REQUIRE(clone->getFileName() == "period.txt");
293 1 : REQUIRE(clone->getSize() == 0);
294 1 : REQUIRE(clone->getTime() == 0); // invalid date
295 1 : REQUIRE(clone->getUnixTime() == 0);
296 1 : REQUIRE_FALSE(clone->hasCrc());
297 1 : REQUIRE_FALSE(clone->isDirectory());
298 1 : REQUIRE_FALSE(clone->isValid());
299 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
300 1 : REQUIRE(clone->isEqual(de));
301 1 : REQUIRE(de.isEqual(*clone));
302 : }
303 : }
304 :
305 24 : WHEN("setting an extra buffer")
306 : {
307 : // zero would not really prove anything so skip such
308 2 : zipios::FileEntry::buffer_t b;
309 1 : uint32_t size(rand() % 100 + 20);
310 78 : for(uint32_t i(0); i < size; ++i)
311 : {
312 77 : b.push_back(rand());
313 : }
314 1 : de.setExtra(b);
315 :
316 2 : THEN("we ignore it")
317 : {
318 1 : REQUIRE(de.getComment().empty());
319 1 : REQUIRE(de.getCompressedSize() == 0);
320 1 : REQUIRE(de.getCrc() == 0);
321 1 : REQUIRE(de.getEntryOffset() == 0);
322 1 : REQUIRE_FALSE(de.getExtra().empty());
323 1 : REQUIRE(de.getHeaderSize() == 0);
324 1 : REQUIRE(de.getLevel() == g_expected_level);
325 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
326 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
327 1 : REQUIRE(de.getFileName() == "period.txt");
328 1 : REQUIRE(de.getSize() == 0);
329 1 : REQUIRE(de.getTime() == 0); // invalid date
330 1 : REQUIRE(de.getUnixTime() == 0);
331 1 : REQUIRE_FALSE(de.hasCrc());
332 1 : REQUIRE_FALSE(de.isDirectory());
333 1 : REQUIRE_FALSE(de.isValid());
334 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
335 1 : REQUIRE(de.getExtra() == b);
336 :
337 2 : zipios::DirectoryEntry other(zipios::FilePath("period.txt"), "");
338 1 : REQUIRE_FALSE(de.isEqual(other));
339 1 : REQUIRE_FALSE(other.isEqual(de));
340 :
341 : // attempt a clone now, should have the same content
342 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
343 :
344 1 : REQUIRE(clone->getComment().empty());
345 1 : REQUIRE(clone->getCompressedSize() == 0);
346 1 : REQUIRE(clone->getCrc() == 0);
347 1 : REQUIRE(clone->getEntryOffset() == 0);
348 1 : REQUIRE_FALSE(clone->getExtra().empty());
349 1 : REQUIRE(clone->getHeaderSize() == 0);
350 1 : REQUIRE(clone->getLevel() == g_expected_level);
351 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
352 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
353 1 : REQUIRE(clone->getFileName() == "period.txt");
354 1 : REQUIRE(clone->getSize() == 0);
355 1 : REQUIRE(clone->getTime() == 0); // invalid date
356 1 : REQUIRE(clone->getUnixTime() == 0);
357 1 : REQUIRE_FALSE(clone->hasCrc());
358 1 : REQUIRE_FALSE(clone->isDirectory());
359 1 : REQUIRE_FALSE(clone->isValid());
360 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
361 1 : REQUIRE(clone->getExtra() == b);
362 1 : REQUIRE(clone->isEqual(de));
363 1 : REQUIRE(de.isEqual(*clone));
364 : }
365 : }
366 :
367 24 : SECTION("setting an invalid level")
368 : {
369 2002 : for(zipios::FileEntry::CompressionLevel level(-1000); level <= 1000; ++level)
370 : {
371 2001 : if(level >= -3 && level <= 100)
372 : {
373 : // this is considered valid
374 104 : de.setLevel(level);
375 :
376 104 : REQUIRE(de.getComment().empty());
377 104 : REQUIRE(de.getCompressedSize() == 0);
378 104 : REQUIRE(de.getCrc() == 0);
379 104 : REQUIRE(de.getEntryOffset() == 0);
380 104 : REQUIRE(de.getExtra().empty());
381 104 : REQUIRE(de.getHeaderSize() == 0);
382 104 : REQUIRE(de.getLevel() == level);
383 104 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
384 104 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
385 104 : REQUIRE(de.getFileName() == "period.txt");
386 104 : REQUIRE(de.getSize() == 0);
387 104 : REQUIRE(de.getTime() == 0); // invalid date
388 104 : REQUIRE(de.getUnixTime() == 0);
389 104 : REQUIRE_FALSE(de.hasCrc());
390 104 : REQUIRE_FALSE(de.isDirectory());
391 104 : REQUIRE_FALSE(de.isValid());
392 104 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
393 :
394 208 : zipios::DirectoryEntry other(zipios::FilePath("/file/really/should/not/exist/period.txt"), "");
395 104 : REQUIRE_FALSE(de.isEqual(other));
396 104 : REQUIRE_FALSE(other.isEqual(de));
397 :
398 : // attempt a clone now, should have the same content
399 208 : zipios::DirectoryEntry::pointer_t clone(de.clone());
400 :
401 104 : REQUIRE(clone->getComment().empty());
402 104 : REQUIRE(clone->getCompressedSize() == 0);
403 104 : REQUIRE(clone->getCrc() == 0);
404 104 : REQUIRE(clone->getEntryOffset() == 0);
405 104 : REQUIRE(clone->getExtra().empty());
406 104 : REQUIRE(clone->getHeaderSize() == 0);
407 104 : REQUIRE(clone->getLevel() == level);
408 104 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
409 104 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
410 104 : REQUIRE(clone->getFileName() == "period.txt");
411 104 : REQUIRE(clone->getSize() == 0);
412 104 : REQUIRE(clone->getTime() == 0); // invalid date
413 104 : REQUIRE(clone->getUnixTime() == 0);
414 104 : REQUIRE_FALSE(clone->hasCrc());
415 104 : REQUIRE_FALSE(clone->isDirectory());
416 104 : REQUIRE_FALSE(clone->isValid());
417 104 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
418 104 : REQUIRE(clone->isEqual(de));
419 208 : REQUIRE(de.isEqual(*clone));
420 : }
421 : else
422 : {
423 1897 : REQUIRE_THROWS_AS(de.setLevel(level), zipios::InvalidStateException);
424 : }
425 : }
426 : }
427 :
428 24 : SECTION("setting an invalid method")
429 : {
430 : // WARNING: the StorageMethod is a uint8_t so testing
431 : // with negative and such would wrap the number...
432 : // (i.e. no need to do more than the following)
433 257 : for(int i(0); i < 256; ++i)
434 : {
435 256 : switch(i)
436 : {
437 : case 0: // Stored
438 : case 8: // Deflated
439 2 : break;
440 :
441 : default:
442 254 : REQUIRE_THROWS_AS(de.setMethod(static_cast<zipios::StorageMethod>(i)), zipios::InvalidStateException);
443 254 : break;
444 :
445 : }
446 : }
447 : }
448 :
449 24 : WHEN("setting the method")
450 : {
451 : // set a method other than STORED, which is 0
452 : // in the newer version, though, the set only accepts
453 : // with STORED and DEFLATED
454 : //
455 1 : zipios::StorageMethod storage_method(zipios::StorageMethod::DEFLATED);
456 1 : de.setMethod(storage_method);
457 :
458 2 : THEN("we ignore it")
459 : {
460 1 : REQUIRE(de.getComment().empty());
461 1 : REQUIRE(de.getCompressedSize() == 0);
462 1 : REQUIRE(de.getCrc() == 0);
463 1 : REQUIRE(de.getEntryOffset() == 0);
464 1 : REQUIRE(de.getExtra().empty());
465 1 : REQUIRE(de.getHeaderSize() == 0);
466 1 : REQUIRE(de.getLevel() == g_expected_level);
467 1 : REQUIRE(de.getMethod() == storage_method);
468 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
469 1 : REQUIRE(de.getFileName() == "period.txt");
470 1 : REQUIRE(de.getSize() == 0);
471 1 : REQUIRE(de.getTime() == 0); // invalid date
472 1 : REQUIRE(de.getUnixTime() == 0);
473 1 : REQUIRE_FALSE(de.hasCrc());
474 1 : REQUIRE_FALSE(de.isDirectory());
475 1 : REQUIRE_FALSE(de.isValid());
476 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
477 :
478 2 : zipios::DirectoryEntry other(zipios::FilePath("/file/really/should/not/exist/period.txt"), "");
479 1 : REQUIRE_FALSE(de.isEqual(other));
480 1 : REQUIRE_FALSE(other.isEqual(de));
481 :
482 : // attempt a clone now, should have the same content
483 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
484 :
485 1 : REQUIRE(clone->getComment().empty());
486 1 : REQUIRE(clone->getCompressedSize() == 0);
487 1 : REQUIRE(clone->getCrc() == 0);
488 1 : REQUIRE(clone->getEntryOffset() == 0);
489 1 : REQUIRE(clone->getExtra().empty());
490 1 : REQUIRE(clone->getHeaderSize() == 0);
491 1 : REQUIRE(clone->getLevel() == g_expected_level);
492 1 : REQUIRE(clone->getMethod() == storage_method);
493 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
494 1 : REQUIRE(clone->getFileName() == "period.txt");
495 1 : REQUIRE(clone->getSize() == 0);
496 1 : REQUIRE(clone->getTime() == 0); // invalid date
497 1 : REQUIRE(clone->getUnixTime() == 0);
498 1 : REQUIRE_FALSE(clone->hasCrc());
499 1 : REQUIRE_FALSE(clone->isDirectory());
500 1 : REQUIRE_FALSE(clone->isValid());
501 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
502 1 : REQUIRE(clone->isEqual(de));
503 1 : REQUIRE(de.isEqual(*clone));
504 : }
505 : }
506 :
507 24 : WHEN("setting the uncompressed size")
508 : {
509 : // zero would not really prove anything so skip such
510 : // (although it may be extremely rare...)
511 : size_t r;
512 0 : do
513 : {
514 1 : r = zipios_test::rand_size_t();
515 : }
516 1 : while(r == 0);
517 1 : de.setSize(r);
518 :
519 2 : THEN("we take it as is")
520 : {
521 1 : REQUIRE(de.getComment().empty());
522 1 : REQUIRE(de.getCompressedSize() == r);
523 1 : REQUIRE(de.getCrc() == 0);
524 1 : REQUIRE(de.getEntryOffset() == 0);
525 1 : REQUIRE(de.getExtra().empty());
526 1 : REQUIRE(de.getHeaderSize() == 0);
527 1 : REQUIRE(de.getLevel() == g_expected_level);
528 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
529 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
530 1 : REQUIRE(de.getFileName() == "period.txt");
531 1 : REQUIRE(de.getSize() == r);
532 1 : REQUIRE(de.getTime() == 0); // invalid date
533 1 : REQUIRE(de.getUnixTime() == 0);
534 1 : REQUIRE(!de.hasCrc());
535 1 : REQUIRE(!de.isDirectory());
536 1 : REQUIRE(!de.isValid());
537 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (" + std::to_string(r) + " bytes)");
538 :
539 2 : zipios::DirectoryEntry other(zipios::FilePath("really/.should"), "");
540 1 : REQUIRE_FALSE(de.isEqual(other));
541 1 : REQUIRE_FALSE(other.isEqual(de));
542 :
543 : // attempt a clone now, should have the same content
544 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
545 :
546 1 : REQUIRE(clone->getComment().empty());
547 1 : REQUIRE(clone->getCompressedSize() == r);
548 1 : REQUIRE(clone->getCrc() == 0);
549 1 : REQUIRE(clone->getEntryOffset() == 0);
550 1 : REQUIRE(clone->getExtra().empty());
551 1 : REQUIRE(clone->getHeaderSize() == 0);
552 1 : REQUIRE(clone->getLevel() == g_expected_level);
553 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
554 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
555 1 : REQUIRE(clone->getFileName() == "period.txt");
556 1 : REQUIRE(clone->getSize() == r);
557 1 : REQUIRE(clone->getTime() == 0); // invalid date
558 1 : REQUIRE(clone->getUnixTime() == 0);
559 1 : REQUIRE(!clone->hasCrc());
560 1 : REQUIRE(!clone->isDirectory());
561 1 : REQUIRE(!clone->isValid());
562 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (" + std::to_string(r) + " bytes)");
563 1 : REQUIRE(clone->isEqual(de));
564 1 : REQUIRE(de.isEqual(*clone));
565 : }
566 : }
567 :
568 24 : WHEN("setting the DOS time")
569 : {
570 : // DOS time numbers are not linear so we test until we get one
571 : // that works...
572 : //
573 1 : std::time_t t((static_cast<std::time_t>(zipios_test::rand_size_t())) % (4354848000LL - 315561600LL) + 315561600);
574 1 : zipios::DOSDateTime r;
575 1 : r.setUnixTimestamp(t);
576 1 : de.setTime(r.getDOSDateTime());
577 :
578 2 : THEN("we take it as is")
579 : {
580 1 : REQUIRE(de.getComment().empty());
581 1 : REQUIRE(de.getCompressedSize() == 0);
582 1 : REQUIRE(de.getCrc() == 0);
583 1 : REQUIRE(de.getEntryOffset() == 0);
584 1 : REQUIRE(de.getExtra().empty());
585 1 : REQUIRE(de.getHeaderSize() == 0);
586 1 : REQUIRE(de.getLevel() == g_expected_level);
587 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
588 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
589 1 : REQUIRE(de.getFileName() == "period.txt");
590 1 : REQUIRE(de.getSize() == 0);
591 1 : REQUIRE(de.getTime() == r.getDOSDateTime());
592 1 : REQUIRE(de.getUnixTime() == r.getUnixTimestamp());
593 1 : REQUIRE(!de.hasCrc());
594 1 : REQUIRE(!de.isDirectory());
595 1 : REQUIRE(!de.isValid());
596 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
597 :
598 2 : zipios::DirectoryEntry other(zipios::FilePath("other-name.txt"), "");
599 1 : REQUIRE_FALSE(de.isEqual(other));
600 1 : REQUIRE_FALSE(other.isEqual(de));
601 :
602 : // attempt a clone now, should have the same content
603 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
604 :
605 1 : REQUIRE(clone->getComment().empty());
606 1 : REQUIRE(clone->getCompressedSize() == 0);
607 1 : REQUIRE(clone->getCrc() == 0);
608 1 : REQUIRE(clone->getEntryOffset() == 0);
609 1 : REQUIRE(clone->getExtra().empty());
610 1 : REQUIRE(clone->getHeaderSize() == 0);
611 1 : REQUIRE(clone->getLevel() == g_expected_level);
612 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
613 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
614 1 : REQUIRE(clone->getFileName() == "period.txt");
615 1 : REQUIRE(clone->getSize() == 0);
616 1 : REQUIRE(clone->getTime() == r.getDOSDateTime());
617 1 : REQUIRE(clone->getUnixTime() == r.getUnixTimestamp());
618 1 : REQUIRE(!clone->hasCrc());
619 1 : REQUIRE(!clone->isDirectory());
620 1 : REQUIRE(!clone->isValid());
621 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
622 1 : REQUIRE(clone->isEqual(de));
623 1 : REQUIRE(de.isEqual(*clone));
624 : }
625 : }
626 :
627 24 : WHEN("setting the Unix time")
628 : {
629 : // DOS time are limited to a smaller range and on every other
630 : // second so we get a valid DOS time and convert it to a Unix time
631 1 : std::time_t r((static_cast<std::time_t>(zipios_test::rand_size_t())) % (4354848000LL - 315561600LL) + 315561600);
632 1 : de.setUnixTime(r);
633 :
634 1 : zipios::DOSDateTime dt;
635 1 : dt.setUnixTimestamp(r);
636 :
637 2 : THEN("we take it as is")
638 : {
639 1 : REQUIRE(de.getComment().empty());
640 1 : REQUIRE(de.getCompressedSize() == 0);
641 1 : REQUIRE(de.getCrc() == 0);
642 1 : REQUIRE(de.getEntryOffset() == 0);
643 1 : REQUIRE(de.getExtra().empty());
644 1 : REQUIRE(de.getHeaderSize() == 0);
645 1 : REQUIRE(de.getLevel() == g_expected_level);
646 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
647 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
648 1 : REQUIRE(de.getFileName() == "period.txt");
649 1 : REQUIRE(de.getSize() == 0);
650 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
651 1 : REQUIRE(de.getUnixTime() == r);
652 1 : REQUIRE(!de.hasCrc());
653 1 : REQUIRE(!de.isDirectory());
654 1 : REQUIRE(!de.isValid());
655 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
656 :
657 2 : zipios::DirectoryEntry other(zipios::FilePath("path/incorrect"), "");
658 1 : REQUIRE_FALSE(de.isEqual(other));
659 1 : REQUIRE_FALSE(other.isEqual(de));
660 :
661 : // attempt a clone now, should have the same content
662 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
663 :
664 1 : REQUIRE(clone->getComment().empty());
665 1 : REQUIRE(clone->getCompressedSize() == 0);
666 1 : REQUIRE(clone->getCrc() == 0);
667 1 : REQUIRE(clone->getEntryOffset() == 0);
668 1 : REQUIRE(clone->getExtra().empty());
669 1 : REQUIRE(clone->getHeaderSize() == 0);
670 1 : REQUIRE(clone->getLevel() == g_expected_level);
671 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
672 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
673 1 : REQUIRE(clone->getFileName() == "period.txt");
674 1 : REQUIRE(clone->getSize() == 0);
675 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
676 1 : REQUIRE(clone->getUnixTime() == r);
677 1 : REQUIRE(!clone->hasCrc());
678 1 : REQUIRE(!clone->isDirectory());
679 1 : REQUIRE(!clone->isValid());
680 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
681 1 : REQUIRE(clone->isEqual(de));
682 1 : REQUIRE(de.isEqual(*clone));
683 : }
684 : }
685 :
686 24 : WHEN("setting the entry offset")
687 : {
688 : // DOS time are limited to a smaller range and on every other
689 : // second so we get a valid DOS time and convert it to a Unix time
690 1 : std::streampos r(zipios_test::rand_size_t());
691 1 : de.setEntryOffset(r);
692 :
693 2 : THEN("we retrieve the same value")
694 : {
695 1 : REQUIRE(de.getComment().empty());
696 1 : REQUIRE(de.getCompressedSize() == 0);
697 1 : REQUIRE(de.getCrc() == 0);
698 1 : REQUIRE(de.getEntryOffset() == r);
699 1 : REQUIRE(de.getExtra().empty());
700 1 : REQUIRE(de.getHeaderSize() == 0);
701 1 : REQUIRE(de.getLevel() == g_expected_level);
702 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
703 1 : REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
704 1 : REQUIRE(de.getFileName() == "period.txt");
705 1 : REQUIRE(de.getSize() == 0);
706 1 : REQUIRE(de.getTime() == 0);
707 1 : REQUIRE(de.getUnixTime() == 0);
708 1 : REQUIRE_FALSE(de.hasCrc());
709 1 : REQUIRE_FALSE(de.isDirectory());
710 1 : REQUIRE_FALSE(de.isValid());
711 1 : REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
712 :
713 2 : zipios::DirectoryEntry other(zipios::FilePath("path/incorrect"), "");
714 1 : REQUIRE_FALSE(de.isEqual(other));
715 1 : REQUIRE_FALSE(other.isEqual(de));
716 :
717 : // attempt a clone now, should have the same content
718 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
719 :
720 1 : REQUIRE(clone->getComment().empty());
721 1 : REQUIRE(clone->getCompressedSize() == 0);
722 1 : REQUIRE(clone->getCrc() == 0);
723 1 : REQUIRE(clone->getEntryOffset() == r);
724 1 : REQUIRE(clone->getExtra().empty());
725 1 : REQUIRE(clone->getHeaderSize() == 0);
726 1 : REQUIRE(clone->getLevel() == g_expected_level);
727 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
728 1 : REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
729 1 : REQUIRE(clone->getFileName() == "period.txt");
730 1 : REQUIRE(clone->getSize() == 0);
731 1 : REQUIRE(clone->getTime() == 0);
732 1 : REQUIRE(clone->getUnixTime() == 0);
733 1 : REQUIRE_FALSE(clone->hasCrc());
734 1 : REQUIRE_FALSE(clone->isDirectory());
735 1 : REQUIRE_FALSE(clone->isValid());
736 1 : REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
737 1 : REQUIRE(clone->isEqual(de));
738 1 : REQUIRE(de.isEqual(*clone));
739 : }
740 : }
741 : }
742 12 : }
743 :
744 :
745 2 : TEST_CASE("DirectoryEntry with one valid file", "[DirectoryEntry] [FileEntry]")
746 : {
747 11 : for(int i(0); i < 10; ++i)
748 : {
749 : // create a random file
750 10 : int const file_size(rand() % 100 + 20);
751 : {
752 : // create a file
753 20 : std::ofstream f("filepath-test.txt", std::ios::out | std::ios::binary);
754 806 : for(int j(0); j < file_size; ++j)
755 : {
756 796 : char const c(rand());
757 796 : f << c;
758 : }
759 : }
760 :
761 : {
762 20 : zipios::DirectoryEntry de(zipios::FilePath("filepath-test.txt"), "");
763 :
764 : struct stat file_stats;
765 10 : REQUIRE(stat("filepath-test.txt", &file_stats) == 0);
766 10 : zipios::DOSDateTime dt;
767 10 : dt.setUnixTimestamp(file_stats.st_mtime);
768 :
769 : {
770 10 : REQUIRE(de.getComment().empty());
771 10 : REQUIRE(de.getCompressedSize() == file_size);
772 10 : REQUIRE(de.getCrc() == 0);
773 10 : REQUIRE(de.getEntryOffset() == 0);
774 10 : REQUIRE(de.getExtra().empty());
775 10 : REQUIRE(de.getHeaderSize() == 0);
776 10 : REQUIRE(de.getLevel() == g_expected_level);
777 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
778 10 : REQUIRE(de.getName() == "filepath-test.txt");
779 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
780 10 : REQUIRE(de.getSize() == file_size);
781 10 : REQUIRE(de.getTime() == dt.getDOSDateTime());
782 10 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
783 10 : REQUIRE(!de.hasCrc());
784 10 : REQUIRE(!de.isDirectory());
785 10 : REQUIRE(de.isValid());
786 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
787 :
788 : // attempt a clone now, should have the same content
789 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
790 :
791 10 : REQUIRE(clone->getComment().empty());
792 10 : REQUIRE(clone->getCompressedSize() == file_size);
793 10 : REQUIRE(clone->getCrc() == 0);
794 10 : REQUIRE(clone->getEntryOffset() == 0);
795 10 : REQUIRE(clone->getExtra().empty());
796 10 : REQUIRE(clone->getHeaderSize() == 0);
797 10 : REQUIRE(clone->getLevel() == g_expected_level);
798 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
799 10 : REQUIRE(clone->getName() == "filepath-test.txt");
800 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
801 10 : REQUIRE(clone->getSize() == file_size);
802 10 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
803 10 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
804 10 : REQUIRE(!clone->hasCrc());
805 10 : REQUIRE(!clone->isDirectory());
806 10 : REQUIRE(clone->isValid());
807 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
808 : }
809 :
810 : {
811 10 : de.setComment("new comment");
812 :
813 10 : REQUIRE(de.getComment() == "new comment");
814 10 : REQUIRE(de.getCompressedSize() == file_size);
815 10 : REQUIRE(de.getCrc() == 0);
816 10 : REQUIRE(de.getEntryOffset() == 0);
817 10 : REQUIRE(de.getExtra().empty());
818 10 : REQUIRE(de.getHeaderSize() == 0);
819 10 : REQUIRE(de.getLevel() == g_expected_level);
820 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
821 10 : REQUIRE(de.getName() == "filepath-test.txt");
822 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
823 10 : REQUIRE(de.getSize() == file_size);
824 10 : REQUIRE(de.getTime() == dt.getDOSDateTime());
825 10 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
826 10 : REQUIRE(!de.hasCrc());
827 10 : REQUIRE(!de.isDirectory());
828 10 : REQUIRE(de.isValid());
829 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
830 :
831 : // attempt a clone now, should have the same content
832 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
833 :
834 10 : REQUIRE(clone->getComment() == "new comment");
835 10 : REQUIRE(clone->getCompressedSize() == file_size);
836 10 : REQUIRE(clone->getCrc() == 0);
837 10 : REQUIRE(clone->getEntryOffset() == 0);
838 10 : REQUIRE(clone->getExtra().empty());
839 10 : REQUIRE(clone->getHeaderSize() == 0);
840 10 : REQUIRE(clone->getLevel() == g_expected_level);
841 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
842 10 : REQUIRE(clone->getName() == "filepath-test.txt");
843 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
844 10 : REQUIRE(clone->getSize() == file_size);
845 10 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
846 10 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
847 10 : REQUIRE(!clone->hasCrc());
848 10 : REQUIRE(!clone->isDirectory());
849 10 : REQUIRE(clone->isValid());
850 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
851 :
852 10 : de.setComment("");
853 : }
854 :
855 : {
856 : // zero would not really prove anything so skip such
857 : // (although it may be extremely rare...)
858 : size_t r;
859 0 : do
860 : {
861 10 : r = zipios_test::rand_size_t();
862 : }
863 10 : while(r == 0);
864 10 : de.setCompressedSize(r);
865 :
866 10 : REQUIRE(de.getComment().empty());
867 10 : REQUIRE(de.getCompressedSize() == file_size);
868 10 : REQUIRE(de.getCrc() == 0);
869 10 : REQUIRE(de.getEntryOffset() == 0);
870 10 : REQUIRE(de.getExtra().empty());
871 10 : REQUIRE(de.getHeaderSize() == 0);
872 10 : REQUIRE(de.getLevel() == g_expected_level);
873 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
874 10 : REQUIRE(de.getName() == "filepath-test.txt");
875 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
876 10 : REQUIRE(de.getSize() == file_size);
877 10 : REQUIRE(de.getTime() == dt.getDOSDateTime());
878 10 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
879 10 : REQUIRE(!de.hasCrc());
880 10 : REQUIRE(!de.isDirectory());
881 10 : REQUIRE(de.isValid());
882 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
883 :
884 : // attempt a clone now, should have the same content
885 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
886 :
887 10 : REQUIRE(clone->getComment().empty());
888 10 : REQUIRE(clone->getCompressedSize() == file_size);
889 10 : REQUIRE(clone->getCrc() == 0);
890 10 : REQUIRE(clone->getEntryOffset() == 0);
891 10 : REQUIRE(clone->getExtra().empty());
892 10 : REQUIRE(clone->getHeaderSize() == 0);
893 10 : REQUIRE(clone->getLevel() == g_expected_level);
894 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
895 10 : REQUIRE(clone->getName() == "filepath-test.txt");
896 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
897 10 : REQUIRE(clone->getSize() == file_size);
898 10 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
899 10 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
900 10 : REQUIRE(!clone->hasCrc());
901 10 : REQUIRE(!clone->isDirectory());
902 10 : REQUIRE(clone->isValid());
903 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
904 : }
905 :
906 : {
907 : // zero would not really prove anything so skip such
908 : uint32_t r;
909 0 : do
910 : {
911 10 : r = rand();
912 : }
913 10 : while(r == 0);
914 10 : de.setCrc(rand());
915 :
916 10 : REQUIRE(de.getComment().empty());
917 10 : REQUIRE(de.getCompressedSize() == file_size);
918 10 : REQUIRE(de.getCrc() == 0);
919 10 : REQUIRE(de.getEntryOffset() == 0);
920 10 : REQUIRE(de.getExtra().empty());
921 10 : REQUIRE(de.getHeaderSize() == 0);
922 10 : REQUIRE(de.getLevel() == g_expected_level);
923 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
924 10 : REQUIRE(de.getName() == "filepath-test.txt");
925 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
926 10 : REQUIRE(de.getSize() == file_size);
927 10 : REQUIRE(de.getTime() == dt.getDOSDateTime());
928 10 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
929 10 : REQUIRE(!de.hasCrc());
930 10 : REQUIRE(!de.isDirectory());
931 10 : REQUIRE(de.isValid());
932 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
933 :
934 : // attempt a clone now, should have the same content
935 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
936 :
937 10 : REQUIRE(clone->getComment().empty());
938 10 : REQUIRE(clone->getCompressedSize() == file_size);
939 10 : REQUIRE(clone->getCrc() == 0);
940 10 : REQUIRE(clone->getEntryOffset() == 0);
941 10 : REQUIRE(clone->getExtra().empty());
942 10 : REQUIRE(clone->getHeaderSize() == 0);
943 10 : REQUIRE(clone->getLevel() == g_expected_level);
944 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
945 10 : REQUIRE(clone->getName() == "filepath-test.txt");
946 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
947 10 : REQUIRE(clone->getSize() == file_size);
948 10 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
949 10 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
950 10 : REQUIRE(!clone->hasCrc());
951 10 : REQUIRE(!clone->isDirectory());
952 10 : REQUIRE(clone->isValid());
953 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
954 : }
955 :
956 : {
957 : // zero would not really prove anything so skip such
958 20 : zipios::FileEntry::buffer_t b;
959 10 : uint32_t size(rand() % 100 + 20);
960 545 : for(uint32_t j(0); j < size; ++j)
961 : {
962 535 : b.push_back(rand());
963 : }
964 10 : de.setExtra(b);
965 :
966 10 : REQUIRE(de.getComment().empty());
967 10 : REQUIRE(de.getCompressedSize() == file_size);
968 10 : REQUIRE(de.getCrc() == 0);
969 10 : REQUIRE(de.getEntryOffset() == 0);
970 10 : REQUIRE_FALSE(de.getExtra().empty());
971 10 : REQUIRE(de.getHeaderSize() == 0);
972 10 : REQUIRE(de.getLevel() == g_expected_level);
973 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
974 10 : REQUIRE(de.getName() == "filepath-test.txt");
975 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
976 10 : REQUIRE(de.getSize() == file_size);
977 10 : REQUIRE(de.getTime() == dt.getDOSDateTime());
978 10 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
979 10 : REQUIRE_FALSE(de.hasCrc());
980 10 : REQUIRE_FALSE(de.isDirectory());
981 10 : REQUIRE(de.isValid());
982 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
983 10 : REQUIRE(de.getExtra() == b);
984 :
985 : // attempt a clone now, should have the same content
986 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
987 :
988 10 : REQUIRE(clone->getComment().empty());
989 10 : REQUIRE(clone->getCompressedSize() == file_size);
990 10 : REQUIRE(clone->getCrc() == 0);
991 10 : REQUIRE(clone->getEntryOffset() == 0);
992 10 : REQUIRE_FALSE(clone->getExtra().empty());
993 10 : REQUIRE(clone->getHeaderSize() == 0);
994 10 : REQUIRE(clone->getLevel() == g_expected_level);
995 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
996 10 : REQUIRE(clone->getName() == "filepath-test.txt");
997 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
998 10 : REQUIRE(clone->getSize() == file_size);
999 10 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1000 10 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1001 10 : REQUIRE_FALSE(clone->hasCrc());
1002 10 : REQUIRE_FALSE(clone->isDirectory());
1003 10 : REQUIRE(clone->isValid());
1004 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
1005 10 : REQUIRE(clone->getExtra() == b);
1006 :
1007 : // reset the buffer
1008 10 : de.setExtra(zipios::FileEntry::buffer_t());
1009 : }
1010 :
1011 20 : SECTION("setting all levels, including many invalid ones")
1012 : {
1013 2002 : for(zipios::FileEntry::CompressionLevel level(-1000); level <= 1000; ++level)
1014 : {
1015 2001 : if(level >= -3 && level <= 100)
1016 : {
1017 : // this is considered valid for a standard file
1018 104 : de.setLevel(level);
1019 :
1020 104 : REQUIRE(de.getComment().empty());
1021 104 : REQUIRE(de.getCompressedSize() == file_size);
1022 104 : REQUIRE(de.getCrc() == 0);
1023 104 : REQUIRE(de.getEntryOffset() == 0);
1024 104 : REQUIRE(de.getExtra().empty());
1025 104 : REQUIRE(de.getHeaderSize() == 0);
1026 104 : REQUIRE(de.getLevel() == level);
1027 104 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1028 104 : REQUIRE(de.getName() == "filepath-test.txt");
1029 104 : REQUIRE(de.getFileName() == "filepath-test.txt");
1030 104 : REQUIRE(de.getSize() == file_size);
1031 104 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1032 104 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1033 104 : REQUIRE_FALSE(de.hasCrc());
1034 104 : REQUIRE_FALSE(de.isDirectory());
1035 104 : REQUIRE(de.isValid());
1036 104 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
1037 : }
1038 : else
1039 : {
1040 1897 : REQUIRE_THROWS_AS(de.setLevel(level), zipios::InvalidStateException);
1041 : }
1042 : }
1043 :
1044 : // restore before continuing test
1045 1 : de.setLevel(g_expected_level);
1046 : }
1047 :
1048 : {
1049 : // set a method other than STORED, which is 1, so just us % 8 instead of % 9 and do a +1
1050 10 : de.setMethod(zipios::StorageMethod::DEFLATED);
1051 :
1052 10 : REQUIRE(de.getComment().empty());
1053 10 : REQUIRE(de.getCompressedSize() == file_size);
1054 10 : REQUIRE(de.getCrc() == 0);
1055 10 : REQUIRE(de.getEntryOffset() == 0);
1056 10 : REQUIRE(de.getExtra().empty());
1057 10 : REQUIRE(de.getHeaderSize() == 0);
1058 10 : REQUIRE(de.getLevel() == g_expected_level);
1059 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
1060 10 : REQUIRE(de.getName() == "filepath-test.txt");
1061 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
1062 10 : REQUIRE(de.getSize() == file_size);
1063 10 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1064 10 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1065 10 : REQUIRE_FALSE(de.hasCrc());
1066 10 : REQUIRE_FALSE(de.isDirectory());
1067 10 : REQUIRE(de.isValid());
1068 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
1069 :
1070 : // attempt a clone now, should have the same content
1071 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1072 :
1073 10 : REQUIRE(clone->getComment().empty());
1074 10 : REQUIRE(clone->getCompressedSize() == file_size);
1075 10 : REQUIRE(clone->getCrc() == 0);
1076 10 : REQUIRE(clone->getEntryOffset() == 0);
1077 10 : REQUIRE(clone->getExtra().empty());
1078 10 : REQUIRE(clone->getHeaderSize() == 0);
1079 10 : REQUIRE(clone->getLevel() == g_expected_level);
1080 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
1081 10 : REQUIRE(clone->getName() == "filepath-test.txt");
1082 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
1083 10 : REQUIRE(clone->getSize() == file_size);
1084 10 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1085 10 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1086 10 : REQUIRE_FALSE(clone->hasCrc());
1087 10 : REQUIRE_FALSE(clone->isDirectory());
1088 10 : REQUIRE(clone->isValid());
1089 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
1090 : }
1091 :
1092 : {
1093 : // zero would not really prove anything so skip such
1094 : // (although it may be extremely rare...)
1095 : size_t r;
1096 : {
1097 10 : r = zipios_test::rand_size_t();
1098 : }
1099 10 : while(r == 0);
1100 10 : de.setSize(r);
1101 :
1102 10 : REQUIRE(de.getComment().empty());
1103 10 : REQUIRE(de.getCompressedSize() == r);
1104 10 : REQUIRE(de.getCrc() == 0);
1105 10 : REQUIRE(de.getEntryOffset() == 0);
1106 10 : REQUIRE(de.getExtra().empty());
1107 10 : REQUIRE(de.getHeaderSize() == 0);
1108 10 : REQUIRE(de.getLevel() == g_expected_level);
1109 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
1110 10 : REQUIRE(de.getName() == "filepath-test.txt");
1111 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
1112 10 : REQUIRE(de.getSize() == r);
1113 10 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1114 10 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1115 10 : REQUIRE(!de.hasCrc());
1116 10 : REQUIRE(!de.isDirectory());
1117 10 : REQUIRE(de.isValid());
1118 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(r) + " bytes)");
1119 :
1120 : // attempt a clone now, should have the same content
1121 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1122 :
1123 10 : REQUIRE(clone->getComment().empty());
1124 10 : REQUIRE(clone->getCompressedSize() == r);
1125 10 : REQUIRE(clone->getCrc() == 0);
1126 10 : REQUIRE(clone->getEntryOffset() == 0);
1127 10 : REQUIRE(clone->getExtra().empty());
1128 10 : REQUIRE(clone->getHeaderSize() == 0);
1129 10 : REQUIRE(clone->getLevel() == g_expected_level);
1130 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
1131 10 : REQUIRE(clone->getName() == "filepath-test.txt");
1132 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
1133 10 : REQUIRE(clone->getSize() == r);
1134 10 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1135 10 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1136 10 : REQUIRE(!clone->hasCrc());
1137 10 : REQUIRE(!clone->isDirectory());
1138 10 : REQUIRE(clone->isValid());
1139 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(r) + " bytes)");
1140 :
1141 10 : de.setSize(file_size);
1142 : }
1143 :
1144 : {
1145 : // DOS time numbers are not linear so we use a Unix date and
1146 : // convert to DOS time (since we know our convertor works)
1147 : //
1148 : // Jan 1, 1980 at 00:00:00 is 315561600 (min)
1149 : // Dec 31, 2107 at 23:59:59 is 4354847999 (max)
1150 10 : std::time_t t(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
1151 10 : zipios::DOSDateTime r;
1152 10 : r.setUnixTimestamp(t);
1153 10 : de.setTime(r.getDOSDateTime());
1154 :
1155 10 : REQUIRE(de.getComment().empty());
1156 10 : REQUIRE(de.getCompressedSize() == file_size);
1157 10 : REQUIRE(de.getCrc() == 0);
1158 10 : REQUIRE(de.getEntryOffset() == 0);
1159 10 : REQUIRE(de.getExtra().empty());
1160 10 : REQUIRE(de.getHeaderSize() == 0);
1161 10 : REQUIRE(de.getLevel() == g_expected_level);
1162 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
1163 10 : REQUIRE(de.getName() == "filepath-test.txt");
1164 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
1165 10 : REQUIRE(de.getSize() == file_size);
1166 10 : REQUIRE(de.getTime() == r.getDOSDateTime());
1167 10 : REQUIRE(de.getUnixTime() == r.getUnixTimestamp()); // WARNING: this is not always equal to t because setTime() may use the next even second
1168 10 : REQUIRE(!de.hasCrc());
1169 10 : REQUIRE(!de.isDirectory());
1170 10 : REQUIRE(de.isValid());
1171 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
1172 :
1173 : // attempt a clone now, should have the same content
1174 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1175 :
1176 10 : REQUIRE(clone->getComment().empty());
1177 10 : REQUIRE(clone->getCompressedSize() == file_size);
1178 10 : REQUIRE(clone->getCrc() == 0);
1179 10 : REQUIRE(clone->getEntryOffset() == 0);
1180 10 : REQUIRE(clone->getExtra().empty());
1181 10 : REQUIRE(clone->getHeaderSize() == 0);
1182 10 : REQUIRE(clone->getLevel() == g_expected_level);
1183 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
1184 10 : REQUIRE(clone->getName() == "filepath-test.txt");
1185 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
1186 10 : REQUIRE(clone->getSize() == file_size);
1187 10 : REQUIRE(clone->getTime() == r.getDOSDateTime());
1188 10 : REQUIRE(clone->getUnixTime() == r.getUnixTimestamp());
1189 10 : REQUIRE(!clone->hasCrc());
1190 10 : REQUIRE(!clone->isDirectory());
1191 10 : REQUIRE(clone->isValid());
1192 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
1193 : }
1194 :
1195 : {
1196 : // DOS time are limited to a smaller range and on every other
1197 : // second so we get a valid DOS time and convert it to a Unix time
1198 10 : std::time_t r(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
1199 10 : zipios::DOSDateTime dr;
1200 10 : dr.setUnixTimestamp(r);
1201 10 : de.setUnixTime(r);
1202 :
1203 10 : REQUIRE(de.getComment().empty());
1204 10 : REQUIRE(de.getCompressedSize() == file_size);
1205 10 : REQUIRE(de.getCrc() == 0);
1206 10 : REQUIRE(de.getEntryOffset() == 0);
1207 10 : REQUIRE(de.getExtra().empty());
1208 10 : REQUIRE(de.getHeaderSize() == 0);
1209 10 : REQUIRE(de.getLevel() == g_expected_level);
1210 10 : REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
1211 10 : REQUIRE(de.getName() == "filepath-test.txt");
1212 10 : REQUIRE(de.getFileName() == "filepath-test.txt");
1213 10 : REQUIRE(de.getSize() == file_size);
1214 10 : REQUIRE(de.getTime() == dr.getDOSDateTime());
1215 10 : REQUIRE(de.getUnixTime() == r);
1216 10 : REQUIRE(!de.hasCrc());
1217 10 : REQUIRE(!de.isDirectory());
1218 10 : REQUIRE(de.isValid());
1219 10 : REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
1220 :
1221 : // attempt a clone now, should have the same content
1222 20 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1223 :
1224 10 : REQUIRE(clone->getComment().empty());
1225 10 : REQUIRE(clone->getCompressedSize() == file_size);
1226 10 : REQUIRE(clone->getCrc() == 0);
1227 10 : REQUIRE(clone->getEntryOffset() == 0);
1228 10 : REQUIRE(clone->getExtra().empty());
1229 10 : REQUIRE(clone->getHeaderSize() == 0);
1230 10 : REQUIRE(clone->getLevel() == g_expected_level);
1231 10 : REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
1232 10 : REQUIRE(clone->getName() == "filepath-test.txt");
1233 10 : REQUIRE(clone->getFileName() == "filepath-test.txt");
1234 10 : REQUIRE(clone->getSize() == file_size);
1235 10 : REQUIRE(clone->getTime() == dr.getDOSDateTime());
1236 10 : REQUIRE(clone->getUnixTime() == r);
1237 10 : REQUIRE(!clone->hasCrc());
1238 10 : REQUIRE(!clone->isDirectory());
1239 10 : REQUIRE(clone->isValid());
1240 10 : REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
1241 : }
1242 : }
1243 :
1244 10 : unlink("filepath-test.txt");
1245 : }
1246 1 : }
1247 :
1248 :
1249 11 : SCENARIO("DirectoryEntry for a valid directory", "[DirectoryEntry] [FileEntry]")
1250 : {
1251 20 : GIVEN("test an existing directory and no comment")
1252 : {
1253 : // make sure the directory is gone before re-creating it
1254 10 : REQUIRE(system("rm -rf filepath-test") == 0);
1255 :
1256 : // create a directory
1257 10 : REQUIRE(mkdir("filepath-test", 0777) == 0);
1258 :
1259 20 : zipios::DirectoryEntry de(zipios::FilePath("filepath-test"), "");
1260 :
1261 : struct stat file_stats;
1262 10 : REQUIRE(stat("filepath-test", &file_stats) == 0);
1263 :
1264 10 : zipios::DOSDateTime dt;
1265 10 : dt.setUnixTimestamp(file_stats.st_mtime);
1266 :
1267 : // first, check that the object is setup as expected
1268 20 : SECTION("verify that the object looks as expected")
1269 : {
1270 1 : REQUIRE(de.getComment().empty());
1271 1 : REQUIRE(de.getCompressedSize() == 0);
1272 1 : REQUIRE(de.getCrc() == 0);
1273 1 : REQUIRE(de.getEntryOffset() == 0);
1274 1 : REQUIRE(de.getExtra().empty());
1275 1 : REQUIRE(de.getHeaderSize() == 0);
1276 1 : REQUIRE(de.getLevel() == g_directory_level);
1277 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1278 1 : REQUIRE(de.getName() == "filepath-test");
1279 1 : REQUIRE(de.getFileName() == "filepath-test");
1280 1 : REQUIRE(de.getSize() == 0);
1281 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1282 1 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1283 1 : REQUIRE(!de.hasCrc());
1284 1 : REQUIRE(de.isDirectory());
1285 1 : REQUIRE(de.isValid());
1286 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1287 :
1288 : // attempt a clone now, should have the same content
1289 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1290 :
1291 1 : REQUIRE(clone->getComment().empty());
1292 1 : REQUIRE(clone->getCompressedSize() == 0);
1293 1 : REQUIRE(clone->getCrc() == 0);
1294 1 : REQUIRE(clone->getEntryOffset() == 0);
1295 1 : REQUIRE(clone->getExtra().empty());
1296 1 : REQUIRE(clone->getHeaderSize() == 0);
1297 1 : REQUIRE(clone->getLevel() == g_directory_level);
1298 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1299 1 : REQUIRE(clone->getName() == "filepath-test");
1300 1 : REQUIRE(clone->getFileName() == "filepath-test");
1301 1 : REQUIRE(clone->getSize() == 0);
1302 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1303 1 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1304 1 : REQUIRE_FALSE(clone->hasCrc());
1305 1 : REQUIRE(clone->isDirectory());
1306 1 : REQUIRE(clone->isValid());
1307 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1308 : }
1309 :
1310 20 : WHEN("setting the comment")
1311 : {
1312 1 : de.setComment("new comment");
1313 :
1314 2 : THEN("we can read it and nothing else changed")
1315 : {
1316 1 : REQUIRE(de.getComment() == "new comment");
1317 1 : REQUIRE(de.getCompressedSize() == 0);
1318 1 : REQUIRE(de.getCrc() == 0);
1319 1 : REQUIRE(de.getEntryOffset() == 0);
1320 1 : REQUIRE(de.getExtra().empty());
1321 1 : REQUIRE(de.getHeaderSize() == 0);
1322 1 : REQUIRE(de.getLevel() == g_directory_level);
1323 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1324 1 : REQUIRE(de.getName() == "filepath-test");
1325 1 : REQUIRE(de.getFileName() == "filepath-test");
1326 1 : REQUIRE(de.getSize() == 0);
1327 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1328 1 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1329 1 : REQUIRE_FALSE(de.hasCrc());
1330 1 : REQUIRE(de.isDirectory());
1331 1 : REQUIRE(de.isValid());
1332 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1333 :
1334 : // attempt a clone now, should have the same content
1335 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1336 :
1337 1 : REQUIRE(clone->getComment() == "new comment");
1338 1 : REQUIRE(clone->getCompressedSize() == 0);
1339 1 : REQUIRE(clone->getCrc() == 0);
1340 1 : REQUIRE(clone->getEntryOffset() == 0);
1341 1 : REQUIRE(clone->getExtra().empty());
1342 1 : REQUIRE(clone->getHeaderSize() == 0);
1343 1 : REQUIRE(clone->getLevel() == g_directory_level);
1344 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1345 1 : REQUIRE(clone->getName() == "filepath-test");
1346 1 : REQUIRE(clone->getFileName() == "filepath-test");
1347 1 : REQUIRE(clone->getSize() == 0);
1348 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1349 1 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1350 1 : REQUIRE_FALSE(clone->hasCrc());
1351 1 : REQUIRE(clone->isDirectory());
1352 1 : REQUIRE(clone->isValid());
1353 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1354 : }
1355 : }
1356 :
1357 20 : WHEN("setting the compressed size")
1358 : {
1359 : // zero would not really prove anything so skip such
1360 : // (although it may be extremely rare...)
1361 : size_t r;
1362 0 : do
1363 : {
1364 1 : r = zipios_test::rand_size_t();
1365 : }
1366 1 : while(r == 0);
1367 1 : de.setCompressedSize(r);
1368 :
1369 2 : THEN("we ignore it")
1370 : {
1371 1 : REQUIRE(de.getComment().empty());
1372 1 : REQUIRE(de.getCompressedSize() == 0);
1373 1 : REQUIRE(de.getCrc() == 0);
1374 1 : REQUIRE(de.getEntryOffset() == 0);
1375 1 : REQUIRE(de.getExtra().empty());
1376 1 : REQUIRE(de.getHeaderSize() == 0);
1377 1 : REQUIRE(de.getLevel() == g_directory_level);
1378 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1379 1 : REQUIRE(de.getName() == "filepath-test");
1380 1 : REQUIRE(de.getFileName() == "filepath-test");
1381 1 : REQUIRE(de.getSize() == 0);
1382 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1383 1 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1384 1 : REQUIRE_FALSE(de.hasCrc());
1385 1 : REQUIRE(de.isDirectory());
1386 1 : REQUIRE(de.isValid());
1387 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1388 :
1389 : // attempt a clone now, should have the same content
1390 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1391 :
1392 1 : REQUIRE(clone->getComment().empty());
1393 1 : REQUIRE(clone->getCompressedSize() == 0);
1394 1 : REQUIRE(clone->getCrc() == 0);
1395 1 : REQUIRE(clone->getEntryOffset() == 0);
1396 1 : REQUIRE(clone->getExtra().empty());
1397 1 : REQUIRE(clone->getHeaderSize() == 0);
1398 1 : REQUIRE(clone->getLevel() == g_directory_level);
1399 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1400 1 : REQUIRE(clone->getName() == "filepath-test");
1401 1 : REQUIRE(clone->getFileName() == "filepath-test");
1402 1 : REQUIRE(clone->getSize() == 0);
1403 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1404 1 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1405 1 : REQUIRE_FALSE(clone->hasCrc());
1406 1 : REQUIRE(clone->isDirectory());
1407 1 : REQUIRE(clone->isValid());
1408 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1409 : }
1410 : }
1411 :
1412 20 : WHEN("setting the CRC")
1413 : {
1414 : // zero would not really prove anything so skip such
1415 : uint32_t r;
1416 0 : do
1417 : {
1418 1 : r = rand();
1419 : }
1420 1 : while(r == 0);
1421 1 : de.setCrc(rand());
1422 :
1423 2 : THEN("we ignore it")
1424 : {
1425 1 : REQUIRE(de.getComment().empty());
1426 1 : REQUIRE(de.getCompressedSize() == 0);
1427 1 : REQUIRE(de.getCrc() == 0);
1428 1 : REQUIRE(de.getEntryOffset() == 0);
1429 1 : REQUIRE(de.getExtra().empty());
1430 1 : REQUIRE(de.getHeaderSize() == 0);
1431 1 : REQUIRE(de.getLevel() == g_directory_level);
1432 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1433 1 : REQUIRE(de.getName() == "filepath-test");
1434 1 : REQUIRE(de.getFileName() == "filepath-test");
1435 1 : REQUIRE(de.getSize() == 0);
1436 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1437 1 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1438 1 : REQUIRE(!de.hasCrc());
1439 1 : REQUIRE(de.isDirectory());
1440 1 : REQUIRE(de.isValid());
1441 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1442 :
1443 : // attempt a clone now, should have the same content
1444 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1445 :
1446 1 : REQUIRE(clone->getComment().empty());
1447 1 : REQUIRE(clone->getCompressedSize() == 0);
1448 1 : REQUIRE(clone->getCrc() == 0);
1449 1 : REQUIRE(clone->getEntryOffset() == 0);
1450 1 : REQUIRE(clone->getExtra().empty());
1451 1 : REQUIRE(clone->getHeaderSize() == 0);
1452 1 : REQUIRE(clone->getLevel() == g_directory_level);
1453 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1454 1 : REQUIRE(clone->getName() == "filepath-test");
1455 1 : REQUIRE(clone->getFileName() == "filepath-test");
1456 1 : REQUIRE(clone->getSize() == 0);
1457 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1458 1 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1459 1 : REQUIRE(!clone->hasCrc());
1460 1 : REQUIRE(clone->isDirectory());
1461 1 : REQUIRE(clone->isValid());
1462 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1463 : }
1464 : }
1465 :
1466 20 : WHEN("setting an extra buffer")
1467 : {
1468 : // zero would not really prove anything so skip such
1469 2 : zipios::FileEntry::buffer_t b;
1470 1 : uint32_t size(rand() % 100 + 20);
1471 38 : for(uint32_t i(0); i < size; ++i)
1472 : {
1473 37 : b.push_back(rand());
1474 : }
1475 1 : de.setExtra(b);
1476 :
1477 2 : THEN("we ignore it")
1478 : {
1479 1 : REQUIRE(de.getComment().empty());
1480 1 : REQUIRE(de.getCompressedSize() == 0);
1481 1 : REQUIRE(de.getCrc() == 0);
1482 1 : REQUIRE(de.getEntryOffset() == 0);
1483 1 : REQUIRE_FALSE(de.getExtra().empty());
1484 1 : REQUIRE(de.getHeaderSize() == 0);
1485 1 : REQUIRE(de.getLevel() == g_directory_level);
1486 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1487 1 : REQUIRE(de.getName() == "filepath-test");
1488 1 : REQUIRE(de.getFileName() == "filepath-test");
1489 1 : REQUIRE(de.getSize() == 0);
1490 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1491 1 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1492 1 : REQUIRE(!de.hasCrc());
1493 1 : REQUIRE(de.isDirectory());
1494 1 : REQUIRE(de.isValid());
1495 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1496 1 : REQUIRE(de.getExtra() == b);
1497 :
1498 : // attempt a clone now, should have the same content
1499 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1500 :
1501 1 : REQUIRE(clone->getComment().empty());
1502 1 : REQUIRE(clone->getCompressedSize() == 0);
1503 1 : REQUIRE(clone->getCrc() == 0);
1504 1 : REQUIRE(clone->getEntryOffset() == 0);
1505 1 : REQUIRE_FALSE(clone->getExtra().empty());
1506 1 : REQUIRE(clone->getHeaderSize() == 0);
1507 1 : REQUIRE(clone->getLevel() == g_directory_level);
1508 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1509 1 : REQUIRE(clone->getName() == "filepath-test");
1510 1 : REQUIRE(clone->getFileName() == "filepath-test");
1511 1 : REQUIRE(clone->getSize() == 0);
1512 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1513 1 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1514 1 : REQUIRE(!clone->hasCrc());
1515 1 : REQUIRE(clone->isDirectory());
1516 1 : REQUIRE(clone->isValid());
1517 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1518 1 : REQUIRE(clone->getExtra() == b);
1519 : }
1520 : }
1521 :
1522 20 : SECTION("setting all levels, including many invalid ones")
1523 : {
1524 2002 : for(zipios::FileEntry::CompressionLevel level(-1000); level <= 1000; ++level)
1525 : {
1526 : // directories do not accept values from 1 to 100
1527 2001 : if(level >= -3 && level <= 0)
1528 : {
1529 : // this is considered valid for a standard file
1530 4 : de.setLevel(level);
1531 :
1532 4 : REQUIRE(de.getComment().empty());
1533 4 : REQUIRE(de.getCompressedSize() == 0);
1534 4 : REQUIRE(de.getCrc() == 0);
1535 4 : REQUIRE(de.getEntryOffset() == 0);
1536 4 : REQUIRE(de.getExtra().empty());
1537 4 : REQUIRE(de.getHeaderSize() == 0);
1538 4 : REQUIRE(de.getLevel() == g_directory_level);
1539 4 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1540 4 : REQUIRE(de.getName() == "filepath-test");
1541 4 : REQUIRE(de.getFileName() == "filepath-test");
1542 4 : REQUIRE(de.getSize() == 0);
1543 4 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1544 4 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1545 4 : REQUIRE_FALSE(de.hasCrc());
1546 4 : REQUIRE(de.isDirectory());
1547 4 : REQUIRE(de.isValid());
1548 4 : REQUIRE(de.toString() == "filepath-test (directory)");
1549 : }
1550 : else
1551 : {
1552 1997 : REQUIRE_THROWS_AS(de.setLevel(level), zipios::InvalidStateException);
1553 : }
1554 : }
1555 :
1556 : // restore before continuing test
1557 1 : de.setLevel(g_expected_level);
1558 : }
1559 :
1560 20 : WHEN("setting the method")
1561 : {
1562 : // set to DEFLATED which has no effect because the de is a
1563 : // directory and directories accept DEFLATED but ignore it
1564 1 : de.setMethod(zipios::StorageMethod::DEFLATED);
1565 :
1566 2 : THEN("we ignore it")
1567 : {
1568 1 : REQUIRE(de.getComment().empty());
1569 1 : REQUIRE(de.getCompressedSize() == 0);
1570 1 : REQUIRE(de.getCrc() == 0);
1571 1 : REQUIRE(de.getEntryOffset() == 0);
1572 1 : REQUIRE(de.getExtra().empty());
1573 1 : REQUIRE(de.getHeaderSize() == 0);
1574 1 : REQUIRE(de.getLevel() == g_directory_level);
1575 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1576 1 : REQUIRE(de.getName() == "filepath-test");
1577 1 : REQUIRE(de.getFileName() == "filepath-test");
1578 1 : REQUIRE(de.getSize() == 0);
1579 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1580 1 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1581 1 : REQUIRE_FALSE(de.hasCrc());
1582 1 : REQUIRE(de.isDirectory());
1583 1 : REQUIRE(de.isValid());
1584 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1585 :
1586 : // attempt a clone now, should have the same content
1587 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1588 :
1589 1 : REQUIRE(clone->getComment().empty());
1590 1 : REQUIRE(clone->getCompressedSize() == 0);
1591 1 : REQUIRE(clone->getCrc() == 0);
1592 1 : REQUIRE(clone->getEntryOffset() == 0);
1593 1 : REQUIRE(clone->getExtra().empty());
1594 1 : REQUIRE(clone->getHeaderSize() == 0);
1595 1 : REQUIRE(clone->getLevel() == g_directory_level);
1596 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1597 1 : REQUIRE(clone->getName() == "filepath-test");
1598 1 : REQUIRE(clone->getFileName() == "filepath-test");
1599 1 : REQUIRE(clone->getSize() == 0);
1600 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1601 1 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1602 1 : REQUIRE_FALSE(clone->hasCrc());
1603 1 : REQUIRE(clone->isDirectory());
1604 1 : REQUIRE(clone->isValid());
1605 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1606 : }
1607 : }
1608 :
1609 20 : WHEN("setting the uncompressed size")
1610 : {
1611 : // zero would not really prove anything so skip such
1612 : // (although it may be extremely rare...)
1613 : size_t r;
1614 0 : do
1615 : {
1616 1 : r = zipios_test::rand_size_t();
1617 : }
1618 1 : while(r == 0);
1619 1 : de.setSize(r);
1620 :
1621 2 : THEN("we take it as is")
1622 : {
1623 1 : REQUIRE(de.getComment().empty());
1624 1 : REQUIRE(de.getCompressedSize() == r);
1625 1 : REQUIRE(de.getCrc() == 0);
1626 1 : REQUIRE(de.getEntryOffset() == 0);
1627 1 : REQUIRE(de.getExtra().empty());
1628 1 : REQUIRE(de.getHeaderSize() == 0);
1629 1 : REQUIRE(de.getLevel() == g_directory_level);
1630 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1631 1 : REQUIRE(de.getName() == "filepath-test");
1632 1 : REQUIRE(de.getFileName() == "filepath-test");
1633 1 : REQUIRE(de.getSize() == r);
1634 1 : REQUIRE(de.getTime() == dt.getDOSDateTime());
1635 1 : REQUIRE(de.getUnixTime() == file_stats.st_mtime);
1636 1 : REQUIRE(!de.hasCrc());
1637 1 : REQUIRE(de.isDirectory());
1638 1 : REQUIRE(de.isValid());
1639 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1640 :
1641 : // attempt a clone now, should have the same content
1642 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1643 :
1644 1 : REQUIRE(clone->getComment().empty());
1645 1 : REQUIRE(clone->getCompressedSize() == r);
1646 1 : REQUIRE(clone->getCrc() == 0);
1647 1 : REQUIRE(clone->getEntryOffset() == 0);
1648 1 : REQUIRE(clone->getExtra().empty());
1649 1 : REQUIRE(clone->getHeaderSize() == 0);
1650 1 : REQUIRE(clone->getLevel() == g_directory_level);
1651 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1652 1 : REQUIRE(clone->getName() == "filepath-test");
1653 1 : REQUIRE(clone->getFileName() == "filepath-test");
1654 1 : REQUIRE(clone->getSize() == r);
1655 1 : REQUIRE(clone->getTime() == dt.getDOSDateTime());
1656 1 : REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
1657 1 : REQUIRE(!clone->hasCrc());
1658 1 : REQUIRE(clone->isDirectory());
1659 1 : REQUIRE(clone->isValid());
1660 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1661 : }
1662 : }
1663 :
1664 20 : WHEN("setting the DOS time")
1665 : {
1666 : // DOS time numbers are not linear so we test until we get one
1667 : // that works...
1668 1 : std::time_t t(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
1669 1 : zipios::DOSDateTime r;
1670 1 : r.setUnixTimestamp(t);
1671 1 : de.setTime(r.getDOSDateTime());
1672 :
1673 2 : THEN("we take it as is")
1674 : {
1675 1 : REQUIRE(de.getComment().empty());
1676 1 : REQUIRE(de.getCompressedSize() == 0);
1677 1 : REQUIRE(de.getCrc() == 0);
1678 1 : REQUIRE(de.getEntryOffset() == 0);
1679 1 : REQUIRE(de.getExtra().empty());
1680 1 : REQUIRE(de.getHeaderSize() == 0);
1681 1 : REQUIRE(de.getLevel() == g_directory_level);
1682 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1683 1 : REQUIRE(de.getName() == "filepath-test");
1684 1 : REQUIRE(de.getFileName() == "filepath-test");
1685 1 : REQUIRE(de.getSize() == 0);
1686 1 : REQUIRE(de.getTime() == r.getDOSDateTime());
1687 1 : REQUIRE(de.getUnixTime() == r.getUnixTimestamp());
1688 1 : REQUIRE(!de.hasCrc());
1689 1 : REQUIRE(de.isDirectory());
1690 1 : REQUIRE(de.isValid());
1691 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1692 :
1693 : // attempt a clone now, should have the same content
1694 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1695 :
1696 1 : REQUIRE(clone->getComment().empty());
1697 1 : REQUIRE(clone->getCompressedSize() == 0);
1698 1 : REQUIRE(clone->getCrc() == 0);
1699 1 : REQUIRE(clone->getEntryOffset() == 0);
1700 1 : REQUIRE(clone->getExtra().empty());
1701 1 : REQUIRE(clone->getHeaderSize() == 0);
1702 1 : REQUIRE(clone->getLevel() == g_directory_level);
1703 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1704 1 : REQUIRE(clone->getName() == "filepath-test");
1705 1 : REQUIRE(clone->getFileName() == "filepath-test");
1706 1 : REQUIRE(clone->getSize() == 0);
1707 1 : REQUIRE(clone->getTime() == r.getDOSDateTime());
1708 1 : REQUIRE(clone->getUnixTime() == r.getUnixTimestamp());
1709 1 : REQUIRE(!clone->hasCrc());
1710 1 : REQUIRE(clone->isDirectory());
1711 1 : REQUIRE(clone->isValid());
1712 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1713 : }
1714 : }
1715 :
1716 20 : WHEN("setting the Unix time")
1717 : {
1718 : // DOS time are limited to a smaller range and on every other
1719 : // second so we get a valid DOS time and convert it to a Unix time
1720 1 : std::time_t r(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
1721 1 : de.setUnixTime(r);
1722 :
1723 1 : zipios::DOSDateTime dr;
1724 1 : dr.setUnixTimestamp(r);
1725 :
1726 2 : THEN("we take it as is")
1727 : {
1728 1 : REQUIRE(de.getComment().empty());
1729 1 : REQUIRE(de.getCompressedSize() == 0);
1730 1 : REQUIRE(de.getCrc() == 0);
1731 1 : REQUIRE(de.getEntryOffset() == 0);
1732 1 : REQUIRE(de.getExtra().empty());
1733 1 : REQUIRE(de.getHeaderSize() == 0);
1734 1 : REQUIRE(de.getLevel() == g_directory_level);
1735 1 : REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
1736 1 : REQUIRE(de.getName() == "filepath-test");
1737 1 : REQUIRE(de.getFileName() == "filepath-test");
1738 1 : REQUIRE(de.getSize() == 0);
1739 1 : REQUIRE(de.getTime() == dr.getDOSDateTime());
1740 1 : REQUIRE(de.getUnixTime() == r);
1741 1 : REQUIRE(!de.hasCrc());
1742 1 : REQUIRE(de.isDirectory());
1743 1 : REQUIRE(de.isValid());
1744 1 : REQUIRE(de.toString() == "filepath-test (directory)");
1745 :
1746 : // attempt a clone now, should have the same content
1747 2 : zipios::DirectoryEntry::pointer_t clone(de.clone());
1748 :
1749 1 : REQUIRE(clone->getComment().empty());
1750 1 : REQUIRE(clone->getCompressedSize() == 0);
1751 1 : REQUIRE(clone->getCrc() == 0);
1752 1 : REQUIRE(clone->getEntryOffset() == 0);
1753 1 : REQUIRE(clone->getExtra().empty());
1754 1 : REQUIRE(clone->getHeaderSize() == 0);
1755 1 : REQUIRE(clone->getLevel() == g_directory_level);
1756 1 : REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
1757 1 : REQUIRE(clone->getName() == "filepath-test");
1758 1 : REQUIRE(clone->getFileName() == "filepath-test");
1759 1 : REQUIRE(clone->getSize() == 0);
1760 1 : REQUIRE(clone->getTime() == dr.getDOSDateTime());
1761 1 : REQUIRE(clone->getUnixTime() == r);
1762 1 : REQUIRE(!clone->hasCrc());
1763 1 : REQUIRE(clone->isDirectory());
1764 1 : REQUIRE(clone->isValid());
1765 1 : REQUIRE(clone->toString() == "filepath-test (directory)");
1766 : }
1767 : }
1768 :
1769 10 : rmdir("filepath-test");
1770 : }
1771 13 : }
1772 :
1773 :
1774 :
1775 :
1776 : // Local Variables:
1777 : // mode: cpp
1778 : // indent-tabs-mode: nil
1779 : // c-basic-offset: 4
1780 : // tab-width: 4
1781 : // End:
1782 :
1783 : // vim: ts=4 sw=4 et
|