diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-02-07 18:20:20 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-02-08 08:29:20 +0100 |
commit | 1be51b107dd08a9575cb07a0a71d459927a85494 (patch) | |
tree | ad4cbc204742f1b2fe3c36a47486b1c20b2a197e /lib/tar/test | |
parent | f0975f9e517edf54811f455f0ce549612d252534 (diff) |
libtar: Add an istream_t implementation
The tar_istream_t reads the data from a tar file, having been given
the header, and synthesizes zero bytes for sparse regions.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/tar/test')
-rw-r--r-- | lib/tar/test/data/CREDITS | 3 | ||||
-rw-r--r-- | lib/tar/test/data/istream/sparse.tar | bin | 0 -> 33792 bytes | |||
-rw-r--r-- | lib/tar/test/tar_istream.c | 73 | ||||
-rw-r--r-- | lib/tar/test/tar_istream2.c | 155 | ||||
-rw-r--r-- | lib/tar/test/tar_istream3.c | 100 |
5 files changed, 331 insertions, 0 deletions
diff --git a/lib/tar/test/data/CREDITS b/lib/tar/test/data/CREDITS index 7a2738f..dab8951 100644 --- a/lib/tar/test/data/CREDITS +++ b/lib/tar/test/data/CREDITS @@ -33,3 +33,6 @@ The following addtional files have been added: Contributed in GitHub issue #64. A tar ball that contains a hard link where the 100 byte target field is completely filled without containing a null-terminator. + - istream/sparse.tar + Derived from sparse/gnu.tar and contains some test data for testing the + tar istream implementation. diff --git a/lib/tar/test/data/istream/sparse.tar b/lib/tar/test/data/istream/sparse.tar Binary files differnew file mode 100644 index 0000000..7f4700d --- /dev/null +++ b/lib/tar/test/data/istream/sparse.tar diff --git a/lib/tar/test/tar_istream.c b/lib/tar/test/tar_istream.c new file mode 100644 index 0000000..cc31282 --- /dev/null +++ b/lib/tar/test/tar_istream.c @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * tar_istream.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "io/file.h" +#include "tar/tar.h" +#include "util/test.h" + +#ifndef TESTUID +#define TESTUID 1000 +#endif + +#ifndef TESTGID +#define TESTGID TESTUID +#endif + +#ifndef TESTFNAME +#define TESTFNAME input.txt +#endif + +#ifndef TESTTS +#define TESTTS 1542905892 +#endif + +static const char *fname = STRVALUE(TESTFNAME); + +int main(int argc, char **argv) +{ + tar_header_decoded_t hdr; + char buffer[100]; + sqfs_s64 ts; + istream_t *fp; + istream_t *ti; + sqfs_s32 ret; + (void)argc; (void)argv; + + fp = istream_open_file(STRVALUE(TESTPATH) "/" STRVALUE(TESTFILE)); + TEST_NOT_NULL(fp); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFREG | 0644); + TEST_EQUAL_UI(hdr.uid, TESTUID); + TEST_EQUAL_UI(hdr.gid, TESTGID); + TEST_EQUAL_UI(hdr.actual_size, 5); + + ts = TESTTS; + TEST_EQUAL_UI(hdr.mtime, ts); + TEST_STR_EQUAL(hdr.name, fname); + TEST_ASSERT(!hdr.unknown_record); + + ti = tar_record_istream_create(fp, &hdr); + TEST_NOT_NULL(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)ti)->refcount, 1); + + ret = istream_read(ti, buffer, sizeof(buffer)); + TEST_EQUAL_I(ret, 5); + buffer[5] = '\0'; + TEST_STR_EQUAL(buffer, "test\n"); + + ret = istream_read(ti, buffer, sizeof(buffer)); + TEST_EQUAL_I(ret, 0); + + clear_header(&hdr); + sqfs_drop(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + sqfs_drop(fp); + return EXIT_SUCCESS; +} diff --git a/lib/tar/test/tar_istream2.c b/lib/tar/test/tar_istream2.c new file mode 100644 index 0000000..a3f27d5 --- /dev/null +++ b/lib/tar/test/tar_istream2.c @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * tar_istream2.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "io/file.h" +#include "tar/tar.h" +#include "util/test.h" + +int main(int argc, char **argv) +{ + tar_header_decoded_t hdr; + char buffer[100]; + istream_t *fp; + istream_t *ti; + (void)argc; (void)argv; + + TEST_ASSERT(chdir(TEST_PATH) == 0); + + fp = istream_open_file("format-acceptance/link_filled.tar"); + TEST_NOT_NULL(fp); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + + /* "deep" directory hierarchy containg 2 files */ + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20_characters_here01/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20_characters_here01/20_characters_here02/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20_characters_here01/20_characters_here02/" + "20_characters_here03/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20_characters_here01/20_characters_here02/" + "20_characters_here03/20_characters_here04/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFREG | 0777); + TEST_STR_EQUAL(hdr.name, "20_characters_here01/20_characters_here02/" + "20_characters_here03/20_characters_here04/" + "errored_file_tst"); + TEST_EQUAL_UI(hdr.actual_size, 5); + + ti = tar_record_istream_create(fp, &hdr); + TEST_NOT_NULL(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)ti)->refcount, 1); + clear_header(&hdr); + + TEST_ASSERT(istream_read(ti, buffer, sizeof(buffer)) == 5); + buffer[5] = '\0'; + TEST_STR_EQUAL(buffer, "test\n"); + TEST_ASSERT(istream_read(ti, buffer, sizeof(buffer)) == 0); + + ti = sqfs_drop(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + + TEST_ASSERT(skip_padding(fp, 5) == 0); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFREG | 0777); + TEST_STR_EQUAL(hdr.name, "20_characters_here01/20_characters_here02/" + "20_characters_here03/20_characters_here04/" + "some_test_file"); + TEST_EQUAL_UI(hdr.actual_size, 5); + + ti = tar_record_istream_create(fp, &hdr); + TEST_NOT_NULL(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)ti)->refcount, 1); + clear_header(&hdr); + + TEST_ASSERT(istream_read(ti, buffer, sizeof(buffer)) == 5); + buffer[5] = '\0'; + TEST_STR_EQUAL(buffer, "test\n"); + TEST_ASSERT(istream_read(ti, buffer, sizeof(buffer)) == 0); + + ti = sqfs_drop(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + + TEST_ASSERT(skip_padding(fp, 5) == 0); + + /* "deep" directory hierarchy containg a hard link */ + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20CharsForLnkTest001/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20CharsForLnkTest001/20CharsForLnkTest002/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20CharsForLnkTest001/20CharsForLnkTest002/" + "20CharsForLnkTest003/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_EQUAL_UI(hdr.mode, S_IFDIR | 0777); + TEST_STR_EQUAL(hdr.name, "20CharsForLnkTest001/20CharsForLnkTest002/" + "20CharsForLnkTest003/20CharsForLnkTest004/"); + clear_header(&hdr); + + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + TEST_STR_EQUAL(hdr.name, "20CharsForLnkTest001/20CharsForLnkTest002/" + "20CharsForLnkTest003/20CharsForLnkTest004/" + "01234567890123456789"); + TEST_ASSERT(hdr.is_hard_link); + + TEST_STR_EQUAL(hdr.link_target, "20_characters_here01/" + "20_characters_here02/20_characters_here03/" + "20_characters_here04/errored_file_tst"); + clear_header(&hdr); + + /* end of file */ + TEST_ASSERT(read_header(fp, &hdr) > 0); + sqfs_drop(fp); + return EXIT_SUCCESS; +} diff --git a/lib/tar/test/tar_istream3.c b/lib/tar/test/tar_istream3.c new file mode 100644 index 0000000..d287081 --- /dev/null +++ b/lib/tar/test/tar_istream3.c @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * tar_istream3.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "io/file.h" +#include "tar/tar.h" +#include "util/test.h" + +static const struct { + uint64_t offset; + size_t size; + int fill; +} regions[] = { + { 0, 4096, 'A' }, + { 262144, 4096, 'B' }, + { 524288, 4096, 'C' }, + { 786432, 4096, 'D' }, + { 1048576, 4096, 'E' }, + { 1310720, 4096, 'F' }, + { 1572864, 4096, 'G' }, + { 1835008, 4096, 'H' }, +}; + +static int byte_from_offset(uint64_t offset) +{ + sqfs_u64 diff; + size_t i; + + for (i = 0; i < sizeof(regions) / sizeof(regions[0]); ++i) { + if (offset >= regions[i].offset) { + diff = (offset - regions[i].offset); + + if (diff < regions[i].size) + return regions[i].fill; + } + } + + return '\0'; +} + +int main(int argc, char **argv) +{ + unsigned char buffer[941]; + tar_header_decoded_t hdr; + istream_t *fp, *ti; + uint64_t offset; + sqfs_s32 i, ret; + (void)argc; (void)argv; + + fp = istream_open_file(STRVALUE(TESTPATH) "/" STRVALUE(TESTFILE)); + TEST_NOT_NULL(fp); + TEST_ASSERT(read_header(fp, &hdr) == 0); + TEST_EQUAL_UI(hdr.mode, S_IFREG | 0644); + TEST_EQUAL_UI(hdr.uid, 01750); + TEST_EQUAL_UI(hdr.gid, 01750); + TEST_EQUAL_UI(hdr.actual_size, 2097152); + TEST_EQUAL_UI(hdr.record_size, 32768); + TEST_STR_EQUAL(hdr.name, "input.bin"); + TEST_ASSERT(!hdr.unknown_record); + + ti = tar_record_istream_create(fp, &hdr); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)ti)->refcount, 1); + clear_header(&hdr); + + offset = 0; + + for (;;) { + ret = istream_read(ti, buffer, sizeof(buffer)); + TEST_ASSERT(ret >= 0); + + if (ret == 0) + break; + + for (i = 0; i < ret; ++i) { + int ref_byte = byte_from_offset(offset + i); + + if (buffer[i] != ref_byte) { + fprintf(stderr, "Byte at offset %llu should " + "be 0x%02X, but is 0x%02X\n", + (unsigned long long)(offset + i), + (unsigned int)ref_byte, buffer[i]); + return EXIT_FAILURE; + } + } + + offset += ret; + TEST_ASSERT(offset <= 2097152); + } + + TEST_EQUAL_UI(offset, 2097152); + + sqfs_drop(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + sqfs_drop(fp); + return EXIT_SUCCESS; +} |