# Test Case: 4-Byte Explicit Extent Physical Address Wrap

**Test ID**: TC155-explicit-extent-pa-wrap
**Category**: Compression Mapping
**Priority**: Critical
**Regression**: Unchecked `pa += plen` can wrap and alias the next extent

## Objective

Verify that every address/index increment used while walking 4-byte explicit
extent records is checked and that a `uint64_t` physical-address wrap returns
`EINTEGRITY` before the wrapped address can be used for I/O.

## Fixture

Generate `extent-pa-wrap.erofs` with:

```sh
python3 tests/review_fixtures.py make \
  --output /work/build/repo22-review-fixes-fixtures
```

erofs-utils 1.8.6 cannot emit explicit extent records, so the helper performs a
minimal structured conversion of a real extended legacy-compressed inode. It
parses the root directory and target inode, then self-checks these fields:

- target `/extent.bin` remains an extended `COMPRESSED_FULL` inode;
- map header has `Z_EROFS_ADVISE_EXTENTS` and record size 4;
- the 64-bit initial physical base is `0xfffffffffffff000`;
- the first two `plen` records are 8192 and 4096;
- `initial_pa + first_plen > UINT64_MAX`;
- the second logical cluster starts at offset 4096;
- the transformed image has a valid recomputed superblock CRC32C.

The second cluster is essential: an unchecked implementation wraps the first
accumulation to 4096 and can present that low address as the second extent.

## Procedure

1. Attach and mount the fixture read-only on FreeBSD 15.
2. Confirm `stat /mnt/repo22-review/extent.bin` succeeds, proving vnode creation
   and map-header parsing completed.
3. Read one byte from logical offset 4096 and capture the syscall with `truss`:

   ```sh
   truss -o extent-wrap.truss \
     dd if=/mnt/repo22-review/extent.bin of=/dev/null bs=1 skip=4096 count=1
   ```

4. Require nonzero `dd` status and a read/pread result of `ERR#97` in the trace.
   Repeat the probe to exercise vnode-cache reuse.
5. Confirm there is no physical read at wrapped offset 4096, panic, trap, or
   assertion in dmesg; then unmount, detach, and unload the module.

## Expected Results

- Both reads fail promptly with FreeBSD `EINTEGRITY` (97).
- No wrapped physical address reaches decompression or device I/O.
- The guest remains responsive and cleanup leaves no EROFS mount, md provider,
  or EROFS module.
