gen_tar_testdata.sh (2713B)
1 #!/bin/sh 2 # This file is part of libextractor. 3 # Copyright (C) 2026 Vidyut Samanta and Christian Grothoff 4 # 5 # Regenerate src/plugins/testdata/tar_test.tar. 6 # 7 # Requires: python3 (standard library only; `tarfile' is part of it). 8 # 9 # Every field the tar plugin reports is set explicitly here, so the test 10 # can assert on exact values: owner name and group name, numeric uid and 11 # gid, the permission bits, the modification times, a symlink target and 12 # a member whose path is long enough to be split across the ustar prefix 13 # field. Nothing is taken from the machine this runs on, so the output 14 # is byte-for-byte reproducible. 15 set -e 16 17 srcdir=$(dirname "$0")/.. 18 out="$srcdir/src/plugins/testdata/tar_test.tar" 19 20 python3 - "$out" <<'EOF' 21 import io 22 import sys 23 import tarfile 24 25 out = sys.argv[1] 26 27 # 2024-03-15T12:34:56Z; the newest mtime in the archive, which is what 28 # the plugin reports as the modification date. 29 NEWEST = 1710506096 30 OLDER = 1700000000 31 32 BODY = b"the quick brown fox jumps over the lazy dog\n" 33 34 35 def member(tf, name, kind, mode, size=0, link=""): 36 ti = tarfile.TarInfo(name) 37 ti.type = kind 38 ti.mode = mode 39 ti.uid = 1000 40 ti.gid = 100 41 ti.uname = "forensic" 42 ti.gname = "analysts" 43 ti.mtime = OLDER 44 ti.linkname = link 45 ti.size = size 46 return ti 47 48 49 with tarfile.open(out, "w", format=tarfile.USTAR_FORMAT) as tf: 50 ti = member(tf, "evidence/", tarfile.DIRTYPE, 0o755) 51 tf.addfile(ti) 52 53 ti = member(tf, "evidence/notes.txt", tarfile.REGTYPE, 0o644, len(BODY)) 54 ti.mtime = NEWEST 55 tf.addfile(ti, io.BytesIO(BODY)) 56 57 ti = member(tf, "evidence/script.sh", tarfile.REGTYPE, 0o755, len(BODY)) 58 tf.addfile(ti, io.BytesIO(BODY)) 59 60 ti = member(tf, "evidence/latest.txt", tarfile.SYMTYPE, 0o777, 61 link="notes.txt") 62 tf.addfile(ti) 63 64 ti = member(tf, "evidence/hardlink.txt", tarfile.LNKTYPE, 0o644, 65 link="evidence/notes.txt") 66 tf.addfile(ti) 67 68 # A member owned by root, so that the plugin has two distinct owners 69 # to report rather than one. 70 ti = member(tf, "evidence/root-owned.txt", tarfile.REGTYPE, 0o600, 71 len(BODY)) 72 ti.uid = 0 73 ti.gid = 0 74 ti.uname = "root" 75 ti.gname = "root" 76 tf.addfile(ti, io.BytesIO(BODY)) 77 78 # 130 characters, so ustar has to split it into the 155-byte prefix 79 # field and the 100-byte name field. 80 long_path = ("evidence/" + "/".join("dir%02d" % i for i in range(15)) 81 + "/deep.txt") 82 assert len(long_path) > 100, len(long_path) 83 ti = member(tf, long_path, tarfile.REGTYPE, 0o640, len(BODY)) 84 tf.addfile(ti, io.BytesIO(BODY)) 85 86 with open(out, "rb") as f: 87 print("wrote %s (%d bytes)" % (out, len(f.read()))) 88 EOF