#!/bin/sh set -eu script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) fixture_dir="$script_dir/fixture" artifact_dir="$script_dir/artifacts" mkdir -p \ "$fixture_dir/alpha/bravo/charlie" \ "$fixture_dir/alpha/sibling" \ "$fixture_dir/wide" \ "$artifact_dir" printf '%s\n' 'cold nested lookup payload' > \ "$fixture_dir/alpha/bravo/charlie/payload.txt" printf '%s\n' 'repeat lookup payload' > \ "$fixture_dir/alpha/bravo/repeat.txt" printf '%s\n' 'sibling marker' > \ "$fixture_dir/alpha/sibling/marker.txt" index=0 while [ "$index" -lt 320 ]; do name=$(printf 'entry-%03d-abcdefghijklmnopqrstuvwxyz.txt' "$index") printf 'wide entry %03d\n' "$index" > "$fixture_dir/wide/$name" index=$((index + 1)) done find "$fixture_dir" -exec touch -h -t 197001010000.00 {} + build_image() { image=$1 mkfs.erofs -d0 -x-1 -T0 --all-time --all-root --workers=1 \ -U 11111111-2222-3333-4444-555555555555 \ "$image" "$fixture_dir" } build_image "$artifact_dir/nested.erofs" build_image "$artifact_dir/nested-repeat.erofs" cmp "$artifact_dir/nested.erofs" "$artifact_dir/nested-repeat.erofs" ARTIFACT_DIR="$artifact_dir" python3 <<'PY' import hashlib import os import shutil import struct artifact_dir = os.environ["ARTIFACT_DIR"] base_path = os.path.join(artifact_dir, "nested.erofs") def u16(image, offset): return struct.unpack_from("> 1) ^ (polynomial if checksum & 1 else 0) put_u32(image, 1024 + 4, checksum & 0xFFFFFFFF) def inode_offset(nid): return nid << 5 def compact_inline_dir(image, nid): offset = inode_offset(nid) inode_format = u16(image, offset) layout = (inode_format >> 1) & 0x7 assert (inode_format & 0x1) == 0 assert layout == 2 assert u16(image, offset + 2) == 0 return offset, offset + 32, u32(image, offset + 8) def dir_entries(image, data_offset, size): first_nameoff = u16(image, data_offset + 8) assert first_nameoff >= 12 assert first_nameoff % 12 == 0 assert first_nameoff < size count = first_nameoff // 12 entries = [] for index in range(count): entry_offset = data_offset + index * 12 nid, nameoff, file_type, reserved = struct.unpack_from( "> 1) & 0x7) == 2 wide_startblk = u32(base, wide_inode + 16) wide_block = wide_startblk << 12 wide_first_nameoff = u16(base, wide_block + 8) wide_count = wide_first_nameoff // 12 wide_last_nameoff = u16(base, wide_block + (wide_count - 1) * 12 + 8) padding_nul = base.index(0, wide_block + wide_last_nameoff, wide_block + 4096) assert padding_nul + 1 < wide_block + 4096 assert base[padding_nul + 1] == 0 bad_padding = bytearray(base) bad_padding[padding_nul + 1] = ord("X") outputs = { "dot-omitted.erofs": dot_omitted, "corrupt-short-block.erofs": short_block, "corrupt-nameoff.erofs": nonmonotonic, "corrupt-padding.erofs": bad_padding, } for filename, image in outputs.items(): update_superblock_checksum(image) path = os.path.join(artifact_dir, filename) with open(path, "wb") as output: output.write(image) with open(os.path.join(artifact_dir, "SHA256SUMS"), "w", encoding="ascii") as sums: for filename in sorted(["nested.erofs", "nested-repeat.erofs", *outputs]): path = os.path.join(artifact_dir, filename) with open(path, "rb") as image_file: digest = hashlib.sha256(image_file.read()).hexdigest() sums.write(f"{digest} {filename}\n") PY cat "$artifact_dir/SHA256SUMS"