From 6351872732fce77186f401050eee92c7c3aa3461 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 20 May 2023 17:04:15 +0200 Subject: libtar: add a dir_iterator_t implementation for tar files The existing istream_t wrapper is mered into this one as well, we can open the files via the iterators open_file_ro function. Unit tests and tar2sqfs are modified accordingly. Signed-off-by: David Oberhollenzer --- lib/tar/test/data/CREDITS | 4 +- lib/tar/test/data/istream/sparse.tar | Bin 33792 -> 0 bytes lib/tar/test/data/iterator/sparse.tar | Bin 0 -> 33792 bytes lib/tar/test/tar_istream.c | 73 -------------- lib/tar/test/tar_istream2.c | 151 ----------------------------- lib/tar/test/tar_istream3.c | 100 -------------------- lib/tar/test/tar_iterator.c | 139 +++++++++++++++++++++++++++ lib/tar/test/tar_iterator2.c | 106 +++++++++++++++++++++ lib/tar/test/tar_iterator3.c | 173 ++++++++++++++++++++++++++++++++++ 9 files changed, 420 insertions(+), 326 deletions(-) delete mode 100644 lib/tar/test/data/istream/sparse.tar create mode 100644 lib/tar/test/data/iterator/sparse.tar delete mode 100644 lib/tar/test/tar_istream.c delete mode 100644 lib/tar/test/tar_istream2.c delete mode 100644 lib/tar/test/tar_istream3.c create mode 100644 lib/tar/test/tar_iterator.c create mode 100644 lib/tar/test/tar_iterator2.c create mode 100644 lib/tar/test/tar_iterator3.c (limited to 'lib/tar/test') diff --git a/lib/tar/test/data/CREDITS b/lib/tar/test/data/CREDITS index 1e7fb32..4c20256 100644 --- a/lib/tar/test/data/CREDITS +++ b/lib/tar/test/data/CREDITS @@ -33,9 +33,9 @@ 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 + - iterator/sparse.tar Derived from sparse/gnu.tar and contains some test data for testing the - tar istream implementation. + tar iterator implementation. - write/simple.tar Created using the tar writer to verify that it works as intended. Used for testing the tar writer to check if it still produces identical diff --git a/lib/tar/test/data/istream/sparse.tar b/lib/tar/test/data/istream/sparse.tar deleted file mode 100644 index 7f4700d..0000000 Binary files a/lib/tar/test/data/istream/sparse.tar and /dev/null differ diff --git a/lib/tar/test/data/iterator/sparse.tar b/lib/tar/test/data/iterator/sparse.tar new file mode 100644 index 0000000..7f4700d Binary files /dev/null and b/lib/tar/test/data/iterator/sparse.tar differ diff --git a/lib/tar/test/tar_istream.c b/lib/tar/test/tar_istream.c deleted file mode 100644 index cc31282..0000000 --- a/lib/tar/test/tar_istream.c +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * tar_istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#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 deleted file mode 100644 index e5cdca8..0000000 --- a/lib/tar/test/tar_istream2.c +++ /dev/null @@ -1,151 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * tar_istream2.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#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_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); - - /* "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 deleted file mode 100644 index d287081..0000000 --- a/lib/tar/test/tar_istream3.c +++ /dev/null @@ -1,100 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * tar_istream3.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#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; -} diff --git a/lib/tar/test/tar_iterator.c b/lib/tar/test/tar_iterator.c new file mode 100644 index 0000000..21bd3e6 --- /dev/null +++ b/lib/tar/test/tar_iterator.c @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * tar_iterator.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "config.h" +#include "io/file.h" +#include "tar/tar.h" +#include "util/test.h" +#include "sqfs/error.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) +{ + istream_t *fp, *ti, *ti2; + dir_iterator_t *it; + dir_entry_t *ent; + char buffer[100]; + sqfs_s32 ret; + sqfs_s64 ts; + (void)argc; (void)argv; + + /* Open the file, create an iterator */ + fp = istream_open_file(STRVALUE(TESTPATH) "/" STRVALUE(TESTFILE)); + TEST_NOT_NULL(fp); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + it = tar_open_stream(fp); + TEST_NOT_NULL(it); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)it)->refcount, 1); + + /* read entry */ + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)it)->refcount, 1); + + ts = TESTTS; + TEST_EQUAL_UI(ent->mode, S_IFREG | 0644); + TEST_EQUAL_UI(ent->uid, TESTUID); + TEST_EQUAL_UI(ent->gid, TESTGID); + TEST_EQUAL_UI(ent->mtime, ts); + TEST_STR_EQUAL(ent->name, fname); + free(ent); + ent = NULL; + + /* Open file stream */ + ret = it->open_file_ro(it, &ti); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)it)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)ti)->refcount, 1); + + /* test that the iterator is now "locked" */ + ret = it->open_file_ro(it, &ti2); + TEST_EQUAL_I(ret, SQFS_ERROR_SEQUENCE); + TEST_NULL(ti2); + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, SQFS_ERROR_SEQUENCE); + TEST_NULL(ent); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)it)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)ti)->refcount, 1); + + /* read the data from the stream */ + 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); + + sqfs_drop(ti); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)it)->refcount, 1); + + /* read past EOF on the iterator */ + ret = it->next(it, &ent); + TEST_ASSERT(ret > 0); + TEST_NULL(ent); + + /* cleanup */ + sqfs_drop(it); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + sqfs_drop(fp); + + /* re-open the tar iterator */ + fp = istream_open_file(STRVALUE(TESTPATH) "/" STRVALUE(TESTFILE)); + TEST_NOT_NULL(fp); + it = tar_open_stream(fp); + TEST_NOT_NULL(it); + + /* read entry */ + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + + ts = TESTTS; + TEST_EQUAL_UI(ent->mode, S_IFREG | 0644); + TEST_EQUAL_UI(ent->uid, TESTUID); + TEST_EQUAL_UI(ent->gid, TESTGID); + TEST_EQUAL_UI(ent->mtime, ts); + TEST_STR_EQUAL(ent->name, fname); + free(ent); + ent = NULL; + + /* read next entry, mus treturn EOF */ + ret = it->next(it, &ent); + TEST_ASSERT(ret > 0); + TEST_NULL(ent); + + /* cleanup */ + sqfs_drop(it); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1); + sqfs_drop(fp); + + return EXIT_SUCCESS; +} diff --git a/lib/tar/test/tar_iterator2.c b/lib/tar/test/tar_iterator2.c new file mode 100644 index 0000000..7f1f3bf --- /dev/null +++ b/lib/tar/test/tar_iterator2.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * tar_iterator2.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#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]; + dir_iterator_t *it; + istream_t *fp, *ti; + dir_entry_t *ent; + uint64_t offset; + sqfs_s32 i, ret; + (void)argc; (void)argv; + + fp = istream_open_file(STRVALUE(TESTPATH) "/" STRVALUE(TESTFILE)); + TEST_NOT_NULL(fp); + it = tar_open_stream(fp); + TEST_NOT_NULL(it); + sqfs_drop(fp); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + + TEST_EQUAL_UI(ent->mode, S_IFREG | 0644); + TEST_EQUAL_UI(ent->uid, 01750); + TEST_EQUAL_UI(ent->gid, 01750); + TEST_EQUAL_UI(ent->size, 2097152); + //TEST_EQUAL_UI(ent->on_disk_size, 32768); + TEST_STR_EQUAL(ent->name, "input.bin"); + free(ent); + + ret = it->open_file_ro(it, &ti); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ti); + + 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(it); + sqfs_drop(ti); + return EXIT_SUCCESS; +} diff --git a/lib/tar/test/tar_iterator3.c b/lib/tar/test/tar_iterator3.c new file mode 100644 index 0000000..b2ad6f9 --- /dev/null +++ b/lib/tar/test/tar_iterator3.c @@ -0,0 +1,173 @@ + +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * tar_iterator3.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "config.h" +#include "io/file.h" +#include "tar/tar.h" +#include "util/test.h" +#include "sqfs/error.h" + +int main(int argc, char **argv) +{ + dir_iterator_t *it; + istream_t *fp, *ti; + char buffer[100]; + dir_entry_t *ent; + char *link; + int ret; + (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); + it = tar_open_stream(fp); + TEST_NOT_NULL(it); + TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 2); + TEST_EQUAL_UI(((sqfs_object_t *)it)->refcount, 1); + sqfs_drop(fp); + + /* "deep" directory hierarchy containg 2 files */ + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20_characters_here01"); + free(ent); + + ret = it->read_link(it, &link); + TEST_EQUAL_I(ret, SQFS_ERROR_NO_ENTRY); + TEST_NULL(link); + ret = it->open_file_ro(it, &ti); + TEST_EQUAL_I(ret, SQFS_ERROR_NOT_FILE); + TEST_NULL(ti); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20_characters_here01/20_characters_here02"); + free(ent); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20_characters_here01/20_characters_here02/" + "20_characters_here03"); + free(ent); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20_characters_here01/20_characters_here02/" + "20_characters_here03/20_characters_here04"); + free(ent); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFREG | 0777); + TEST_STR_EQUAL(ent->name, "20_characters_here01/20_characters_here02/" + "20_characters_here03/20_characters_here04/" + "errored_file_tst"); + free(ent); + + ret = it->read_link(it, &link); + TEST_EQUAL_I(ret, SQFS_ERROR_NO_ENTRY); + TEST_NULL(link); + ret = it->open_file_ro(it, &ti); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ti); + + 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); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFREG | 0777); + TEST_STR_EQUAL(ent->name, "20_characters_here01/20_characters_here02/" + "20_characters_here03/20_characters_here04/" + "some_test_file"); + free(ent); + + ret = it->open_file_ro(it, &ti); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ti); + + 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); + + /* "deep" directory hierarchy containg a hard link */ + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20CharsForLnkTest001"); + free(ent); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20CharsForLnkTest001/20CharsForLnkTest002"); + free(ent); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20CharsForLnkTest001/20CharsForLnkTest002/" + "20CharsForLnkTest003"); + free(ent); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_EQUAL_UI(ent->mode, S_IFDIR | 0777); + TEST_STR_EQUAL(ent->name, "20CharsForLnkTest001/20CharsForLnkTest002/" + "20CharsForLnkTest003/20CharsForLnkTest004"); + free(ent); + + ret = it->next(it, &ent); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(ent); + TEST_STR_EQUAL(ent->name, "20CharsForLnkTest001/20CharsForLnkTest002/" + "20CharsForLnkTest003/20CharsForLnkTest004/" + "01234567890123456789"); + TEST_EQUAL_UI(ent->mode, S_IFLNK | 0777); + TEST_ASSERT((ent->flags & DIR_ENTRY_FLAG_HARD_LINK) != 0); + free(ent); + + ret = it->read_link(it, &link); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(link); + ret = it->open_file_ro(it, &ti); + TEST_EQUAL_I(ret, SQFS_ERROR_NOT_FILE); + TEST_NULL(ti); + + TEST_STR_EQUAL(link, "20_characters_here01/" + "20_characters_here02/20_characters_here03/" + "20_characters_here04/errored_file_tst"); + free(link); + + /* end of file */ + ret = it->next(it, &ent); + TEST_ASSERT(ret > 0); + TEST_NULL(ent); + sqfs_drop(it); + return EXIT_SUCCESS; +} -- cgit v1.2.3