libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

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