aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-01-31 11:30:46 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-01-31 18:04:25 +0100
commit72c8155d9fc0eaeac72c053f46ebb7b231d4596a (patch)
tree5758865289c52fa93f56e3fe743bb40c283c5233 /bin
parentcdccc69c62579b0c13b35fad0728079652b8f3c9 (diff)
Reintegrate test code with library code
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'bin')
-rw-r--r--bin/gensquashfs/Makemodule.am64
-rw-r--r--bin/gensquashfs/test/filemap_xattr.c98
-rw-r--r--bin/gensquashfs/test/fstree1.txt10
-rw-r--r--bin/gensquashfs/test/fstree_from_dir.c178
-rw-r--r--bin/gensquashfs/test/fstree_from_file.c93
-rw-r--r--bin/gensquashfs/test/fstree_fuzz.c34
-rw-r--r--bin/gensquashfs/test/fstree_glob1.c246
-rw-r--r--bin/gensquashfs/test/fstree_glob1.txt2
-rw-r--r--bin/gensquashfs/test/fstree_glob2.txt3
-rw-r--r--bin/gensquashfs/test/fstree_glob3.txt2
-rw-r--r--bin/gensquashfs/test/sort_file.c217
-rw-r--r--bin/gensquashfs/test/testdir/dira/file_a00
-rw-r--r--bin/gensquashfs/test/testdir/dira/file_a10
-rw-r--r--bin/gensquashfs/test/testdir/dira/file_a20
-rw-r--r--bin/gensquashfs/test/testdir/dirb/file_b00
-rw-r--r--bin/gensquashfs/test/testdir/dirb/file_b10
-rw-r--r--bin/gensquashfs/test/testdir/dirb/file_b20
-rw-r--r--bin/gensquashfs/test/testdir/dirc/file_c00
-rw-r--r--bin/gensquashfs/test/testdir/dirc/file_c10
-rw-r--r--bin/gensquashfs/test/testdir/dirc/file_c20
-rw-r--r--bin/gensquashfs/test/xattr1.txt9
-rw-r--r--bin/rdsquashfs/Makemodule.am8
-rw-r--r--bin/rdsquashfs/test/pathtraversal.sh.in12
-rw-r--r--bin/rdsquashfs/test/pathtraversal.sqfsbin0 -> 4096 bytes
-rw-r--r--bin/tar2sqfs/Makemodule.am6
-rw-r--r--bin/tar2sqfs/test/simple.tarbin0 -> 20480 bytes
-rw-r--r--bin/tar2sqfs/test/sqfs.sha51228
-rwxr-xr-xbin/tar2sqfs/test/test_tar_sqfs.sh.in34
28 files changed, 1044 insertions, 0 deletions
diff --git a/bin/gensquashfs/Makemodule.am b/bin/gensquashfs/Makemodule.am
index 7edc39a..052f692 100644
--- a/bin/gensquashfs/Makemodule.am
+++ b/bin/gensquashfs/Makemodule.am
@@ -17,3 +17,67 @@ endif
dist_man1_MANS += bin/gensquashfs/gensquashfs.1
bin_PROGRAMS += gensquashfs
+
+GENDATADIR=$(top_srcdir)/bin/gensquashfs/test
+
+test_filemap_xattr_SOURCES = bin/gensquashfs/test/filemap_xattr.c \
+ bin/gensquashfs/src/filemap_xattr.c \
+ bin/gensquashfs/src/mkfs.h
+test_filemap_xattr_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
+test_filemap_xattr_CPPFLAGS += -DTESTPATH=$(GENDATADIR)/xattr1.txt
+test_filemap_xattr_LDADD = libsquashfs.la libfstree.a libutil.a
+test_filemap_xattr_LDADD += libio.a libcompat.a
+
+test_fstree_from_file_SOURCES = bin/gensquashfs/test/fstree_from_file.c \
+ bin/gensquashfs/src/fstree_from_file.c \
+ bin/gensquashfs/src/fstree_from_dir.c \
+ bin/gensquashfs/src/mkfs.h
+test_fstree_from_file_CPPFLAGS = $(AM_CPPFLAGS)
+test_fstree_from_file_CPPFLAGS += -I$(top_srcdir)/bin/gensquashfs/src
+test_fstree_from_file_CPPFLAGS += -DTESTPATH=$(GENDATADIR)/fstree1.txt
+test_fstree_from_file_LDADD = libfstree.a libio.a libutil.a libcompat.a
+
+test_fstree_glob1_SOURCES = bin/gensquashfs/test/fstree_glob1.c \
+ bin/gensquashfs/src/fstree_from_file.c \
+ bin/gensquashfs/src/fstree_from_dir.c \
+ bin/gensquashfs/src/mkfs.h
+test_fstree_glob1_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
+test_fstree_glob1_CPPFLAGS += -DTESTPATH=$(GENDATADIR)
+test_fstree_glob1_LDADD = libfstree.a libio.a libutil.a libcompat.a
+
+test_fstree_from_dir_SOURCES = bin/gensquashfs/test/fstree_from_dir.c \
+ bin/gensquashfs/src/fstree_from_dir.c \
+ bin/gensquashfs/src/mkfs.h
+test_fstree_from_dir_CPPFLAGS = $(AM_CPPFLAGS)
+test_fstree_from_dir_CPPFLAGS += -I$(top_srcdir)/bin/gensquashfs/src
+test_fstree_from_dir_CPPFLAGS += -DTESTPATH=$(GENDATADIR)/testdir
+test_fstree_from_dir_LDADD = libfstree.a libutil.a libcompat.a
+
+test_sort_file_SOURCES = bin/gensquashfs/test/sort_file.c \
+ bin/gensquashfs/src/fstree_from_file.c \
+ bin/gensquashfs/src/fstree_from_dir.c \
+ bin/gensquashfs/src/sort_by_file.c \
+ bin/gensquashfs/src/mkfs.h
+test_sort_file_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
+test_sort_file_LDADD = libfstree.a libio.a libutil.a libcompat.a
+
+fstree_fuzz_SOURCES = bin/gensquashfs/test/fstree_fuzz.c \
+ bin/gensquashfs/src/fstree_from_file.c \
+ bin/gensquashfs/src/fstree_from_dir.c \
+ bin/gensquashfs/src/mkfs.h
+fstree_fuzz_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
+fstree_fuzz_LDADD = libfstree.a libio.a libutil.a libcompat.a
+
+GENSQUASHFS_TESTS = \
+ test_filemap_xattr test_fstree_from_file test_fstree_from_dir \
+ test_fstree_glob1 test_sort_file
+
+noinst_PROGRAMS += fstree_fuzz
+
+check_PROGRAMS += $(GENSQUASHFS_TESTS)
+TESTS += $(GENSQUASHFS_TESTS)
+
+EXTRA_DIST += $(GENDATADIR)/xattr1.txt $(GENDATADIR)/fstree1.txt
+EXTRA_DIST += $(GENDATADIR)/fstree_glob1.txt $(GENDATADIR)/fstree_glob2.txt
+EXTRA_DIST += $(GENDATADIR)/fstree_glob3.txt
+EXTRA_DIST += $(GENDATADIR)/testdir
diff --git a/bin/gensquashfs/test/filemap_xattr.c b/bin/gensquashfs/test/filemap_xattr.c
new file mode 100644
index 0000000..d258d89
--- /dev/null
+++ b/bin/gensquashfs/test/filemap_xattr.c
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * filemap_xattr.c
+ *
+ * Copyright (C) 2022 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "util/test.h"
+#include "mkfs.h"
+
+static const char *dev_selinux = "system_u:object_r:device_t:s0";
+static const char *zero_selinux = "system_u:object_r:zero_device_t:s0";
+static const char *rfkill_selinux = "system_u:object_r:wireless_device_t:s0";
+
+static const sqfs_u8 rfkill_acl[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x06, 0x00,
+ 0xe8, 0x03, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x06, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x04, 0x00,
+ 0xff, 0xff, 0xff, 0xff
+};
+
+int main(int argc, char **argv)
+{
+ struct XattrMapPattern *pat;
+ struct XattrMapEntry *ent;
+ struct XattrMap *map;
+ int ret;
+ (void)argc; (void)argv;
+
+ map = xattr_open_map_file(TEST_PATH);
+ TEST_NOT_NULL(map);
+
+ /* the third pattern */
+ pat = map->patterns;
+ TEST_NOT_NULL(pat);
+ TEST_STR_EQUAL(pat->path, "dev/rfkill");
+
+ ent = pat->entries;
+ TEST_NOT_NULL(ent);
+ TEST_STR_EQUAL(ent->key, "system.posix_acl_access");
+
+ TEST_EQUAL_UI(ent->value_len, sizeof(rfkill_acl));
+ ret = memcmp(ent->value, rfkill_acl, ent->value_len);
+ TEST_EQUAL_I(ret, 0);
+
+ ent = ent->next;
+ TEST_NOT_NULL(ent);
+ TEST_STR_EQUAL(ent->key, "security.selinux");
+
+ TEST_EQUAL_UI(ent->value_len, strlen(rfkill_selinux));
+ ret = memcmp(ent->value, rfkill_selinux, ent->value_len);
+ TEST_EQUAL_I(ret, 0);
+
+ ent = ent->next;
+ TEST_NULL(ent);
+
+ /* the second pattern */
+ pat = pat->next;
+ TEST_NOT_NULL(pat);
+ TEST_STR_EQUAL(pat->path, "dev/zero");
+
+ ent = pat->entries;
+ TEST_NOT_NULL(ent);
+ TEST_STR_EQUAL(ent->key, "security.selinux");
+
+ TEST_EQUAL_UI(ent->value_len, strlen(zero_selinux));
+ ret = memcmp(ent->value, zero_selinux, ent->value_len);
+ TEST_EQUAL_I(ret, 0);
+
+ ent = ent->next;
+ TEST_NULL(ent);
+
+ /* the first pattern */
+ pat = pat->next;
+ TEST_NOT_NULL(pat);
+ TEST_STR_EQUAL(pat->path, "dev");
+
+ ent = pat->entries;
+ TEST_NOT_NULL(ent);
+ TEST_STR_EQUAL(ent->key, "security.selinux");
+
+ TEST_EQUAL_UI(ent->value_len, strlen(dev_selinux));
+ ret = memcmp(ent->value, dev_selinux, ent->value_len);
+ TEST_EQUAL_I(ret, 0);
+
+ ent = ent->next;
+ TEST_NULL(ent);
+
+ /* no more patterns */
+ pat = pat->next;
+ TEST_NULL(pat);
+
+ xattr_close_map_file(map);
+ return EXIT_SUCCESS;
+}
diff --git a/bin/gensquashfs/test/fstree1.txt b/bin/gensquashfs/test/fstree1.txt
new file mode 100644
index 0000000..95ee469
--- /dev/null
+++ b/bin/gensquashfs/test/fstree1.txt
@@ -0,0 +1,10 @@
+# comment line
+slink /slink 0644 2 3 slinktarget
+dir /dir 0755 4 5
+nod /chardev 0600 6 7 c 13 37
+nod /blkdev 0600 8 9 b 42 21
+pipe /pipe 0644 10 11
+dir / 0755 1000 100
+dir "/foo bar" 0755 0 0
+dir "/foo bar/ test \"/" 0755 0 0
+ sock /sock 0555 12 13 \ No newline at end of file
diff --git a/bin/gensquashfs/test/fstree_from_dir.c b/bin/gensquashfs/test/fstree_from_dir.c
new file mode 100644
index 0000000..5e73fa4
--- /dev/null
+++ b/bin/gensquashfs/test/fstree_from_dir.c
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * fstree_from_dir.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "util/test.h"
+#include "mkfs.h"
+
+static void check_hierarchy(tree_node_t *root, bool recursive)
+{
+ tree_node_t *n, *m;
+
+ n = root->data.dir.children;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "dira");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == root);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_a0");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_a1");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_a2");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "dirb");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == root);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_b0");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_b1");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_b2");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "dirc");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == root);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_c0");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_c1");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "file_c2");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NULL(n);
+}
+
+int main(int argc, char **argv)
+{
+ struct stat sb;
+ tree_node_t *n;
+ fstree_t fs;
+ (void)argc; (void)argv;
+
+ /* recursively scan into root */
+ TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_from_dir(&fs, fs.root, TEST_PATH,
+ NULL, NULL, 0) == 0);
+
+ fstree_post_process(&fs);
+ check_hierarchy(fs.root, true);
+ fstree_cleanup(&fs);
+
+ /* non-recursively scan into root */
+ TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_from_dir(&fs, fs.root, TEST_PATH, NULL, NULL,
+ DIR_SCAN_NO_RECURSION) == 0);
+
+ fstree_post_process(&fs);
+ check_hierarchy(fs.root, false);
+ fstree_cleanup(&fs);
+
+ /* recursively scan into a sub-directory of root */
+ memset(&sb, 0, sizeof(sb));
+ sb.st_mode = S_IFDIR | 0755;
+
+ TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+
+ n = fstree_mknode(fs.root, "foodir", 6, NULL, &sb);
+ TEST_NOT_NULL(n);
+ fs.root->data.dir.children = n;
+
+ TEST_ASSERT(fstree_from_dir(&fs, n, TEST_PATH, NULL, NULL, 0) == 0);
+
+ TEST_ASSERT(fs.root->data.dir.children == n);
+ TEST_NULL(n->next);
+
+ fstree_post_process(&fs);
+ check_hierarchy(n, true);
+ fstree_cleanup(&fs);
+
+ /* non-recursively scan into a sub-directory of root */
+ memset(&sb, 0, sizeof(sb));
+ sb.st_mode = S_IFDIR | 0755;
+
+ TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+
+ n = fstree_mknode(fs.root, "foodir", 6, NULL, &sb);
+ TEST_NOT_NULL(n);
+ fs.root->data.dir.children = n;
+
+ TEST_ASSERT(fstree_from_dir(&fs, n, TEST_PATH, NULL, NULL,
+ DIR_SCAN_NO_RECURSION) == 0);
+
+ TEST_ASSERT(fs.root->data.dir.children == n);
+ TEST_NULL(n->next);
+
+ fstree_post_process(&fs);
+ check_hierarchy(n, false);
+ fstree_cleanup(&fs);
+
+ return EXIT_SUCCESS;
+}
diff --git a/bin/gensquashfs/test/fstree_from_file.c b/bin/gensquashfs/test/fstree_from_file.c
new file mode 100644
index 0000000..2a9ba1e
--- /dev/null
+++ b/bin/gensquashfs/test/fstree_from_file.c
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * fstree_from_file.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "util/test.h"
+#include "mkfs.h"
+
+int main(int argc, char **argv)
+{
+ tree_node_t *n;
+ fstree_t fs;
+ (void)argc; (void)argv;
+
+ TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_from_file(&fs, TEST_PATH, NULL) == 0);
+
+ fstree_post_process(&fs);
+ n = fs.root->data.dir.children;
+
+ TEST_EQUAL_UI(fs.root->link_count, 9);
+ TEST_EQUAL_UI(fs.root->mode, S_IFDIR | 0755);
+ TEST_EQUAL_UI(fs.root->uid, 1000);
+ TEST_EQUAL_UI(fs.root->gid, 100);
+
+ TEST_EQUAL_UI(n->mode, S_IFBLK | 0600);
+ TEST_EQUAL_UI(n->uid, 8);
+ TEST_EQUAL_UI(n->gid, 9);
+ TEST_EQUAL_UI(n->link_count, 1);
+ TEST_STR_EQUAL(n->name, "blkdev");
+ TEST_EQUAL_UI(n->data.devno, makedev(42, 21));
+
+ n = n->next;
+ TEST_EQUAL_UI(n->mode, S_IFCHR | 0600);
+ TEST_EQUAL_UI(n->uid, 6);
+ TEST_EQUAL_UI(n->gid, 7);
+ TEST_EQUAL_UI(n->link_count, 1);
+ TEST_STR_EQUAL(n->name, "chardev");
+ TEST_EQUAL_UI(n->data.devno, makedev(13, 37));
+
+ n = n->next;
+ TEST_EQUAL_UI(n->mode, S_IFDIR | 0755);
+ TEST_EQUAL_UI(n->uid, 4);
+ TEST_EQUAL_UI(n->gid, 5);
+ TEST_EQUAL_UI(n->link_count, 2);
+ TEST_STR_EQUAL(n->name, "dir");
+ TEST_NULL(n->data.dir.children);
+
+ n = n->next;
+ TEST_EQUAL_UI(n->mode, S_IFDIR | 0755);
+ TEST_EQUAL_UI(n->uid, 0);
+ TEST_EQUAL_UI(n->gid, 0);
+ TEST_EQUAL_UI(n->link_count, 3);
+ TEST_STR_EQUAL(n->name, "foo bar");
+ TEST_NOT_NULL(n->data.dir.children);
+
+ TEST_NULL(n->data.dir.children->next);
+ TEST_EQUAL_UI(n->data.dir.children->mode, S_IFDIR | 0755);
+ TEST_EQUAL_UI(n->data.dir.children->uid, 0);
+ TEST_EQUAL_UI(n->data.dir.children->gid, 0);
+ TEST_EQUAL_UI(n->data.dir.children->link_count, 2);
+ TEST_STR_EQUAL(n->data.dir.children->name, " test \"");
+ TEST_NULL(n->data.dir.children->data.dir.children);
+
+ n = n->next;
+ TEST_EQUAL_UI(n->mode, S_IFIFO | 0644);
+ TEST_EQUAL_UI(n->uid, 10);
+ TEST_EQUAL_UI(n->gid, 11);
+ TEST_EQUAL_UI(n->link_count, 1);
+ TEST_STR_EQUAL(n->name, "pipe");
+
+ n = n->next;
+ TEST_EQUAL_UI(n->mode, S_IFLNK | 0777);
+ TEST_EQUAL_UI(n->uid, 2);
+ TEST_EQUAL_UI(n->gid, 3);
+ TEST_EQUAL_UI(n->link_count, 1);
+ TEST_STR_EQUAL(n->name, "slink");
+ TEST_STR_EQUAL(n->data.target, "slinktarget");
+
+ n = n->next;
+ TEST_EQUAL_UI(n->mode, S_IFSOCK | 0555);
+ TEST_EQUAL_UI(n->uid, 12);
+ TEST_EQUAL_UI(n->gid, 13);
+ TEST_EQUAL_UI(n->link_count, 1);
+ TEST_STR_EQUAL(n->name, "sock");
+ TEST_NULL(n->next);
+
+ fstree_cleanup(&fs);
+ return EXIT_SUCCESS;
+}
diff --git a/bin/gensquashfs/test/fstree_fuzz.c b/bin/gensquashfs/test/fstree_fuzz.c
new file mode 100644
index 0000000..4fbb72b
--- /dev/null
+++ b/bin/gensquashfs/test/fstree_fuzz.c
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * fstree_fuzz.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "mkfs.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ int ret = EXIT_FAILURE;
+ fstree_t fs;
+
+ if (argc != 2) {
+ fputs("Usage: fstree_fuzz <input_file>\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ if (fstree_init(&fs, NULL))
+ return EXIT_FAILURE;
+
+ if (fstree_from_file(&fs, argv[1], NULL))
+ goto out_fs;
+
+ ret = EXIT_SUCCESS;
+out_fs:
+ fstree_cleanup(&fs);
+ return ret;
+}
diff --git a/bin/gensquashfs/test/fstree_glob1.c b/bin/gensquashfs/test/fstree_glob1.c
new file mode 100644
index 0000000..fbcbf91
--- /dev/null
+++ b/bin/gensquashfs/test/fstree_glob1.c
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * fstree_glob1.c
+ *
+ * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "util/test.h"
+#include "mkfs.h"
+
+static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive)
+{
+ tree_node_t *n, *m, *parentdir;
+
+ if (subdir) {
+ n = root->data.dir.children;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "tarcorpus");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == root);
+ TEST_NULL(n->next);
+ } else {
+ n = root;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_NULL(n->parent);
+ TEST_NULL(n->next);
+ }
+
+ parentdir = n;
+ n = n->data.dir.children;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "file-size");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "format-acceptance");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu-g.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "large-mtime");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "long-paths");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "negative-mtime");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "sparse-files");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu-small.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "pax-gnu0-0.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "pax-gnu0-1.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "pax-gnu1-0.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "user-group-largenum");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+
+ if (recursive) {
+ m = n->data.dir.children;
+ TEST_NOT_NULL(m);
+ TEST_STR_EQUAL(m->name, "gnu.tar");
+ TEST_ASSERT(S_ISREG(m->mode));
+ TEST_ASSERT(m->parent == n);
+
+ m = m->next;
+ TEST_NULL(m);
+ } else {
+ TEST_NULL(n->data.dir.children);
+ }
+
+ n = n->next;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "xattr");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == parentdir);
+ TEST_NULL(n->data.dir.children);
+
+ n = n->next;
+ TEST_NULL(n);
+}
+
+int main(int argc, char **argv)
+{
+ fstree_t fs;
+ int ret;
+ (void)argc; (void)argv;
+
+ /* first test case, directory tree only */
+ ret = fstree_init(&fs, NULL);
+ TEST_EQUAL_I(ret, 0);
+
+ ret = fstree_from_file(&fs, TEST_PATH "/fstree_glob1.txt", TEST_PATH);
+ TEST_EQUAL_I(ret, 0);
+
+ fstree_post_process(&fs);
+ check_hierarchy(fs.root, true, false);
+ fstree_cleanup(&fs);
+
+ /* first test case, directory tree plus fnmatch()ed files */
+ ret = fstree_init(&fs, NULL);
+ TEST_EQUAL_I(ret, 0);
+
+ ret = fstree_from_file(&fs, TEST_PATH "/fstree_glob2.txt", TEST_PATH);
+ TEST_EQUAL_I(ret, 0);
+
+ fstree_post_process(&fs);
+ check_hierarchy(fs.root, true, true);
+ fstree_cleanup(&fs);
+
+ /* third test case, same as second, but entries directly at the root */
+ ret = fstree_init(&fs, NULL);
+ TEST_EQUAL_I(ret, 0);
+
+ ret = fstree_from_file(&fs, TEST_PATH "/fstree_glob3.txt", TEST_PATH);
+ TEST_EQUAL_I(ret, 0);
+
+ fstree_post_process(&fs);
+ check_hierarchy(fs.root, false, true);
+ fstree_cleanup(&fs);
+ return EXIT_SUCCESS;
+}
diff --git a/bin/gensquashfs/test/fstree_glob1.txt b/bin/gensquashfs/test/fstree_glob1.txt
new file mode 100644
index 0000000..e3e2902
--- /dev/null
+++ b/bin/gensquashfs/test/fstree_glob1.txt
@@ -0,0 +1,2 @@
+dir /tarcorpus 0755 0 0
+glob /tarcorpus 0755 0 0 -type d -- ../../../lib/tar/test/data
diff --git a/bin/gensquashfs/test/fstree_glob2.txt b/bin/gensquashfs/test/fstree_glob2.txt
new file mode 100644
index 0000000..7c9bd1a
--- /dev/null
+++ b/bin/gensquashfs/test/fstree_glob2.txt
@@ -0,0 +1,3 @@
+dir /tarcorpus 0755 0 0
+glob /tarcorpus 0755 0 0 -type d ../../../lib/tar/test/data
+glob /tarcorpus 0644 0 0 -type f -name "*gnu*.tar" -- ../../../lib/tar/test/data
diff --git a/bin/gensquashfs/test/fstree_glob3.txt b/bin/gensquashfs/test/fstree_glob3.txt
new file mode 100644
index 0000000..9ef48cf
--- /dev/null
+++ b/bin/gensquashfs/test/fstree_glob3.txt
@@ -0,0 +1,2 @@
+glob / 0755 0 0 -type d ../../../lib/tar/test/data
+glob / 0644 0 0 -type f -name "*gnu*.tar" -- ../../../lib/tar/test/data
diff --git a/bin/gensquashfs/test/sort_file.c b/bin/gensquashfs/test/sort_file.c
new file mode 100644
index 0000000..951328e
--- /dev/null
+++ b/bin/gensquashfs/test/sort_file.c
@@ -0,0 +1,217 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * sort_file.c
+ *
+ * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "sqfs/block.h"
+#include "util/test.h"
+#include "util/util.h"
+#include "mkfs.h"
+
+static const char *listing =
+"dir /bin 0755 0 0\n"
+"dir /lib 0755 0 0\n"
+"dir /usr 0755 0 0\n"
+"dir /usr/share 0755 0 0\n"
+"\n"
+"file /bin/chown 0755 0 0\n"
+"file /bin/ls 0755 0 0\n"
+"file /bin/chmod 0755 0 0\n"
+"file /bin/dir 0755 0 0\n"
+"file /bin/cp 0755 0 0\n"
+"file /bin/dd 0755 0 0\n"
+"file /bin/ln 0755 0 0\n"
+"file /bin/mkdir 0755 0 0\n"
+"file /bin/mknod 0755 0 0\n"
+"\n"
+"file /lib/libssl.so 0755 0 0\n"
+"file /lib/libfoobar.so 0755 0 0\n"
+"file /lib/libwhatever.so 0755 0 0\n"
+"\n"
+"file /usr/share/bla.txt 0644 0 0\n";
+
+static const char *sort_file =
+"# Blockwise reverse the order of the /bin files\n"
+" 10 [glob] /bin/mk*\n"
+" 20 [glob] /bin/ch*\n"
+" 30 [glob] /bin/d*\n"
+" 40 /bin/cp\n"
+" 50 [glob] /bin/*\n"
+"\n"
+"# Make this file appear first\n"
+" -10000 [dont_compress,dont_fragment,align] /usr/share/bla.txt";
+
+static const char *initial_order[] = {
+ "bin/chmod",
+ "bin/chown",
+ "bin/cp",
+ "bin/dd",
+ "bin/dir",
+ "bin/ln",
+ "bin/ls",
+ "bin/mkdir",
+ "bin/mknod",
+ "lib/libfoobar.so",
+ "lib/libssl.so",
+ "lib/libwhatever.so",
+ "usr/share/bla.txt",
+};
+
+static const char *after_sort_order[] = {
+ "usr/share/bla.txt",
+ "lib/libfoobar.so",
+ "lib/libssl.so",
+ "lib/libwhatever.so",
+ "bin/mkdir",
+ "bin/mknod",
+ "bin/chmod",
+ "bin/chown",
+ "bin/dd",
+ "bin/dir",
+ "bin/cp",
+ "bin/ln",
+ "bin/ls",
+};
+
+static sqfs_s64 priorities[] = {
+ -10000,
+ 0,
+ 0,
+ 0,
+ 10,
+ 10,
+ 20,
+ 20,
+ 30,
+ 30,
+ 40,
+ 50,
+ 50,
+};
+
+static int flags[] = {
+ SQFS_BLK_DONT_COMPRESS | SQFS_BLK_ALIGN | SQFS_BLK_DONT_FRAGMENT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+/*****************************************************************************/
+
+static sqfs_u8 temp_buffer[2048];
+static const char *input_file = NULL;
+
+static void destroy_noop(sqfs_object_t *obj)
+{
+ (void)obj;
+}
+
+static int memfile_load(istream_t *strm)
+{
+ strcpy((char *)temp_buffer, input_file);
+ strm->eof = true;
+ strm->buffer_used = strlen(input_file);
+ return 0;
+}
+
+static const char *get_filename(istream_t *strm)
+{
+ (void)strm;
+ return "memstream";
+}
+
+static istream_t memstream = {
+ .base = {
+ .destroy = destroy_noop,
+ },
+
+ .buffer_used = 0,
+ .buffer_offset = 0,
+ .eof = false,
+ .buffer = temp_buffer,
+
+ .precache = memfile_load,
+ .get_filename = get_filename,
+};
+
+/*****************************************************************************/
+
+int main(int argc, char **argv)
+{
+ file_info_t *fi;
+ fstree_t fs;
+ size_t i;
+ (void)argc; (void)argv;
+
+ input_file = listing;
+ memstream.buffer_used = 0;
+ memstream.buffer_offset = 0;
+ memstream.eof = false;
+
+ TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_from_file_stream(&fs, &memstream, NULL) == 0);
+
+ fstree_post_process(&fs);
+
+ for (i = 0, fi = fs.files; fi != NULL; fi = fi->next, ++i) {
+ tree_node_t *n = container_of(fi, tree_node_t, data.file);
+ char *path = fstree_get_path(n);
+ int ret;
+
+ TEST_NOT_NULL(path);
+
+ ret = canonicalize_name(path);
+ TEST_EQUAL_I(ret, 0);
+
+ TEST_STR_EQUAL(initial_order[i], path);
+ free(path);
+
+ TEST_EQUAL_I(fi->priority, 0);
+ TEST_EQUAL_I(fi->flags, 0);
+ }
+
+ TEST_EQUAL_UI(i, sizeof(initial_order) / sizeof(initial_order[0]));
+
+
+ input_file = sort_file;
+ memstream.buffer_used = 0;
+ memstream.buffer_offset = 0;
+ memstream.eof = false;
+
+ TEST_ASSERT(fstree_sort_files(&fs, &memstream) == 0);
+
+ for (i = 0, fi = fs.files; fi != NULL; fi = fi->next, ++i) {
+ tree_node_t *n = container_of(fi, tree_node_t, data.file);
+ char *path = fstree_get_path(n);
+ int ret;
+
+ TEST_NOT_NULL(path);
+
+ ret = canonicalize_name(path);
+ TEST_EQUAL_I(ret, 0);
+
+ TEST_STR_EQUAL(after_sort_order[i], path);
+ free(path);
+
+ TEST_EQUAL_I(fi->priority, priorities[i]);
+ TEST_EQUAL_I(fi->flags, flags[i]);
+ }
+
+ TEST_EQUAL_UI(i, sizeof(after_sort_order) /
+ sizeof(after_sort_order[0]));
+
+ fstree_cleanup(&fs);
+ return EXIT_SUCCESS;
+}
diff --git a/bin/gensquashfs/test/testdir/dira/file_a0 b/bin/gensquashfs/test/testdir/dira/file_a0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dira/file_a0
diff --git a/bin/gensquashfs/test/testdir/dira/file_a1 b/bin/gensquashfs/test/testdir/dira/file_a1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dira/file_a1
diff --git a/bin/gensquashfs/test/testdir/dira/file_a2 b/bin/gensquashfs/test/testdir/dira/file_a2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dira/file_a2
diff --git a/bin/gensquashfs/test/testdir/dirb/file_b0 b/bin/gensquashfs/test/testdir/dirb/file_b0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dirb/file_b0
diff --git a/bin/gensquashfs/test/testdir/dirb/file_b1 b/bin/gensquashfs/test/testdir/dirb/file_b1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dirb/file_b1
diff --git a/bin/gensquashfs/test/testdir/dirb/file_b2 b/bin/gensquashfs/test/testdir/dirb/file_b2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dirb/file_b2
diff --git a/bin/gensquashfs/test/testdir/dirc/file_c0 b/bin/gensquashfs/test/testdir/dirc/file_c0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dirc/file_c0
diff --git a/bin/gensquashfs/test/testdir/dirc/file_c1 b/bin/gensquashfs/test/testdir/dirc/file_c1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dirc/file_c1
diff --git a/bin/gensquashfs/test/testdir/dirc/file_c2 b/bin/gensquashfs/test/testdir/dirc/file_c2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bin/gensquashfs/test/testdir/dirc/file_c2
diff --git a/bin/gensquashfs/test/xattr1.txt b/bin/gensquashfs/test/xattr1.txt
new file mode 100644
index 0000000..ffe5fec
--- /dev/null
+++ b/bin/gensquashfs/test/xattr1.txt
@@ -0,0 +1,9 @@
+# file: dev/
+security.selinux="system_u:object_r:device_t:s0"
+
+# file: dev/zero
+security.selinux="system_u:object_r:zero_device_t:s0"
+
+# file: dev/rfkill
+security.selinux="system_u:object_r:wireless_device_t:s0"
+system.posix_acl_access=0sAgAAAAEABgD/////AgAGAOgDAAAEAAYA/////xAABgD/////IAAEAP////8=
diff --git a/bin/rdsquashfs/Makemodule.am b/bin/rdsquashfs/Makemodule.am
index f8f9d3d..380883e 100644
--- a/bin/rdsquashfs/Makemodule.am
+++ b/bin/rdsquashfs/Makemodule.am
@@ -9,3 +9,11 @@ rdsquashfs_LDADD += libfstree.a $(LZO_LIBS) $(PTHREAD_LIBS)
dist_man1_MANS += bin/rdsquashfs/rdsquashfs.1
bin_PROGRAMS += rdsquashfs
+
+if WINDOWS
+else
+check_SCRIPTS += bin/rdsquashfs/test/pathtraversal.sh
+TESTS += bin/rdsquashfs/test/pathtraversal.sh
+endif
+
+EXTRA_DIST += $(top_srcdir)/bin/rdsquashfs/test/pathtraversal.sqfs
diff --git a/bin/rdsquashfs/test/pathtraversal.sh.in b/bin/rdsquashfs/test/pathtraversal.sh.in
new file mode 100644
index 0000000..5b19c4d
--- /dev/null
+++ b/bin/rdsquashfs/test/pathtraversal.sh.in
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+RDSQFS="@abs_top_builddir@/rdsquashfs"
+REFFILE="@abs_top_srcdir@/bin/rdsquashfs/test/pathtraversal.sqfs"
+GOTCHA="/tmp/gotcha.txt"
+
+if "$RDSQFS" -u / -p . "$REFFILE"; then
+ if [ -e "$GOTCHA" ]; then
+ echo "Found $GOTCHA which should not be there"
+ exit 1
+ fi
+fi
diff --git a/bin/rdsquashfs/test/pathtraversal.sqfs b/bin/rdsquashfs/test/pathtraversal.sqfs
new file mode 100644
index 0000000..0c33bb3
--- /dev/null
+++ b/bin/rdsquashfs/test/pathtraversal.sqfs
Binary files differ
diff --git a/bin/tar2sqfs/Makemodule.am b/bin/tar2sqfs/Makemodule.am
index c8f52ea..920b226 100644
--- a/bin/tar2sqfs/Makemodule.am
+++ b/bin/tar2sqfs/Makemodule.am
@@ -8,3 +8,9 @@ tar2sqfs_LDADD += $(PTHREAD_LIBS)
dist_man1_MANS += bin/tar2sqfs/tar2sqfs.1
bin_PROGRAMS += tar2sqfs
+
+check_SCRIPTS += bin/tar2sqfs/test/test_tar_sqfs.sh
+TESTS += bin/tar2sqfs/test/test_tar_sqfs.sh
+
+EXTRA_DIST += $(top_srcdir)/bin/tar2sqfs/test/simple.tar
+EXTRA_DIST += $(top_srcdir)/bin/tar2sqfs/test/sqfs.sha512
diff --git a/bin/tar2sqfs/test/simple.tar b/bin/tar2sqfs/test/simple.tar
new file mode 100644
index 0000000..ba1020b
--- /dev/null
+++ b/bin/tar2sqfs/test/simple.tar
Binary files differ
diff --git a/bin/tar2sqfs/test/sqfs.sha512 b/bin/tar2sqfs/test/sqfs.sha512
new file mode 100644
index 0000000..609e154
--- /dev/null
+++ b/bin/tar2sqfs/test/sqfs.sha512
@@ -0,0 +1,28 @@
+6217c207d51e38bd819ff70047a070d0172c2e1cc97ba5feb578a2429d1c911bd7990ea845b28389a956754e52e5693beba38c124bf6d7452522361a81c2da09 test_tar/data/long-paths/gnu.sqfs
+6217c207d51e38bd819ff70047a070d0172c2e1cc97ba5feb578a2429d1c911bd7990ea845b28389a956754e52e5693beba38c124bf6d7452522361a81c2da09 test_tar/data/long-paths/pax.sqfs
+6217c207d51e38bd819ff70047a070d0172c2e1cc97ba5feb578a2429d1c911bd7990ea845b28389a956754e52e5693beba38c124bf6d7452522361a81c2da09 test_tar/data/long-paths/ustar.sqfs
+2e2cd5fa04304c5765d7bb54c30273be6cd7414150ae95d217efcec1fbaa7486b4e752adb95e0dddd5329355132baaa7260dc958eb4418158a249929e89b0581 test_tar/data/sparse-files/gnu-small.sqfs
+f48a79c58db4d3553ffde5bd3780bb34c12fd0ee703aba95a40588c1cf7b5a679ea16d2a842a11e262bd14c2f0b4dd256436dcfc72a177a455427f93b504eae6 test_tar/data/sparse-files/gnu.sqfs
+f48a79c58db4d3553ffde5bd3780bb34c12fd0ee703aba95a40588c1cf7b5a679ea16d2a842a11e262bd14c2f0b4dd256436dcfc72a177a455427f93b504eae6 test_tar/data/sparse-files/pax-gnu0-1.sqfs
+f48a79c58db4d3553ffde5bd3780bb34c12fd0ee703aba95a40588c1cf7b5a679ea16d2a842a11e262bd14c2f0b4dd256436dcfc72a177a455427f93b504eae6 test_tar/data/sparse-files/pax-gnu0-0.sqfs
+f48a79c58db4d3553ffde5bd3780bb34c12fd0ee703aba95a40588c1cf7b5a679ea16d2a842a11e262bd14c2f0b4dd256436dcfc72a177a455427f93b504eae6 test_tar/data/sparse-files/pax-gnu1-0.sqfs
+194384a9a3683ef751f45ca9f380790b3bd9c234a839ff72b09c778f96fe521be9d816c7d3179edf936ec35cd66fad2485b03482468629baa3290a1475c72147 test_tar/data/large-mtime/12-digit.sqfs
+194384a9a3683ef751f45ca9f380790b3bd9c234a839ff72b09c778f96fe521be9d816c7d3179edf936ec35cd66fad2485b03482468629baa3290a1475c72147 test_tar/data/large-mtime/gnu.sqfs
+194384a9a3683ef751f45ca9f380790b3bd9c234a839ff72b09c778f96fe521be9d816c7d3179edf936ec35cd66fad2485b03482468629baa3290a1475c72147 test_tar/data/large-mtime/pax.sqfs
+c40037ae4a4b4224a919cf18c238d5a6b13f17fcca2602810e870e7606435f61426417cda32dd9bca85e74ec6c0fc75c996f60ec8b4560e79c83631937b6cdfa test_tar/data/negative-mtime/gnu.sqfs
+c40037ae4a4b4224a919cf18c238d5a6b13f17fcca2602810e870e7606435f61426417cda32dd9bca85e74ec6c0fc75c996f60ec8b4560e79c83631937b6cdfa test_tar/data/negative-mtime/pax.sqfs
+d3d112eab3537f6784a207d0bfd8f2826908fbddb3cf20e379a646c6c587c8bbaa67a1753a4ee0246c110dc10bd0ce821fa58368936efac3a1bbf8fd3f782e2b test_tar/data/format-acceptance/gnu-g.sqfs
+d3d112eab3537f6784a207d0bfd8f2826908fbddb3cf20e379a646c6c587c8bbaa67a1753a4ee0246c110dc10bd0ce821fa58368936efac3a1bbf8fd3f782e2b test_tar/data/format-acceptance/gnu.sqfs
+d3d112eab3537f6784a207d0bfd8f2826908fbddb3cf20e379a646c6c587c8bbaa67a1753a4ee0246c110dc10bd0ce821fa58368936efac3a1bbf8fd3f782e2b test_tar/data/format-acceptance/ustar-pre-posix.sqfs
+d3d112eab3537f6784a207d0bfd8f2826908fbddb3cf20e379a646c6c587c8bbaa67a1753a4ee0246c110dc10bd0ce821fa58368936efac3a1bbf8fd3f782e2b test_tar/data/format-acceptance/v7.sqfs
+d3d112eab3537f6784a207d0bfd8f2826908fbddb3cf20e379a646c6c587c8bbaa67a1753a4ee0246c110dc10bd0ce821fa58368936efac3a1bbf8fd3f782e2b test_tar/data/format-acceptance/pax.sqfs
+d3d112eab3537f6784a207d0bfd8f2826908fbddb3cf20e379a646c6c587c8bbaa67a1753a4ee0246c110dc10bd0ce821fa58368936efac3a1bbf8fd3f782e2b test_tar/data/format-acceptance/ustar.sqfs
+20eb111e2019eca4f26535e52823593ebf6a6b2c35d7a8779d6e4f92b90cba8e41edaf1f92425b5084adc680a7c0dac758a2f5170e0b4f19db3ea3357fb3080a test_tar/data/format-acceptance/link_filled.sqfs
+a5e95c464f41249da9a4156db3a23d30e01652881e839912f632f2614f1775e62a3fed184efbec1a25148f43edf7ba2a92e1136416aca4bf8f3e73a3b137162b test_tar/data/user-group-largenum/gnu.sqfs
+428728b2ca26543a9b0e698d1ae4f54463a7912b51248f2bd34627eb20f3abd8469379a5cd71ab6903aedd198ef48c97e66385c22f128e8aa08571f669c4c6c6 test_tar/data/user-group-largenum/8-digit.sqfs
+a5e95c464f41249da9a4156db3a23d30e01652881e839912f632f2614f1775e62a3fed184efbec1a25148f43edf7ba2a92e1136416aca4bf8f3e73a3b137162b test_tar/data/user-group-largenum/pax.sqfs
+6ff3ae611d295fc597db088f82ccd0218220ffb51ed901f0d1027c68d687f917b1601bf096421281fb95df48fb2aa6e5f1dc81caccbaa914cb971e17a2c4d5cd test_tar/data/xattr/xattr-schily-binary.sqfs
+627a69ed25f9b5380d269fbe12603818d73b29d6a1155fcf7bebca2ba30ec1cce7b8405394498333f9847f10f0768b80b94b723551dbff10c633d2887e62b804 test_tar/data/xattr/xattr-schily.sqfs
+627a69ed25f9b5380d269fbe12603818d73b29d6a1155fcf7bebca2ba30ec1cce7b8405394498333f9847f10f0768b80b94b723551dbff10c633d2887e62b804 test_tar/data/xattr/xattr-libarchive.sqfs
+b8e0e1cb41663c3d6278bf214234ac00ae8b86b9bc16d086bd0a7bfa9b0d28d626f70c6a1bd6f05dbbfa46431ce3f4518a4be38caf87b1f071d57edae24c5b10 test_tar/data/xattr/acl.sqfs
+bae693082a771c500c2d6b52a8eeb91decd98e90eaae379951bcc80589533ff43b58375f8a7f3de77c35456ee7fb269a6b17e4c29b291475578ba8453f152d0e test_tar/root-becomes.sqfs
diff --git a/bin/tar2sqfs/test/test_tar_sqfs.sh.in b/bin/tar2sqfs/test/test_tar_sqfs.sh.in
new file mode 100755
index 0000000..eb25fd9
--- /dev/null
+++ b/bin/tar2sqfs/test/test_tar_sqfs.sh.in
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+set -e
+
+TARDIR="@abs_top_srcdir@/lib/tar/test/data"
+TARDIR2="@abs_top_srcdir@/bin/tar2sqfs/test"
+SHA512FILE="$TARDIR2/sqfs.sha512"
+TAR2SQFS="@abs_top_builddir@/tar2sqfs"
+
+if [ ! -f "$TAR2SQFS" -a -f "${TAR2SQFS}.exe" ]; then
+ TAR2SQFS="${TAR2SQFS}.exe"
+fi
+
+# process tar files used for conformance tests
+for filename in $(find "$TARDIR" -name "*.tar" | grep -v ".*/file-size/.*"); do
+ dir="$(dirname $filename | sed -n -e 's;.*/test/;test_tar/;p')"
+ imgname="$dir/$(basename $filename .tar).sqfs"
+
+ mkdir -p "$dir"
+ "$TAR2SQFS" --defaults mtime=0 -c gzip -q "$imgname" < "$filename"
+done
+
+# edge case test
+filename="$TARDIR2/simple.tar"
+imgname="./test_tar/root-becomes.sqfs"
+
+"$TAR2SQFS" --root-becomes foo --defaults mtime=0 \
+ -c gzip -q "$imgname" < "$filename"
+
+# verify
+sha512sum -c "$SHA512FILE"
+
+# cleanup
+rm -rf "./test_tar"