open
https://gitlab.synchro.net/main/sbbs/-/work_items/1286
## Summary
libarchive's mtree reader claims plain text files whose first lines are single tokens (number lists, word lists, one-name-per-line `.lst` files), and reading them then fails with:
```
archive_read_next_header() returned -20: Missing type keyword in mtree specification
```
mtree is a BSD manifest format (a text list of paths with `type=`/`mode=`/`size=` attributes). It contains no file data, so it is never a useful "archive" on a BBS. It is enabled because every read site calls `archive_read_support_format_all()`, and libarchive offers no way to exclude one format from that set.
Found while testing the #1278 fix (b958104a19, landing-13-joined, 2026-10-16). Not caused by it: HEAD before that commit behaves the same.
## Reproduce
```
$ seq 1 50 > words.txt
$ jsexec -n -r 'print(new Archive("words.txt").list())'
Error: archive_read_next_header() returned -20: Missing type keyword in mtree specification
```
Without an `#mtree` signature line, libarchive guesses from the first lines, and a line holding a single token passes as "a path with no keywords". Text with spaces in its lines (logs, Markdown, source code) is not affected.
## Effects
- **Uncompressed text file:** fails either way. Only the error text differs from the expected "Unrecognized archive format".
- **Compressed text file** (e.g. a `.gz` of a word list): since #1278 this should list as a single-entry "raw" archive, but mtree claims the decompressed text first, so it still fails.
- **A genuine mtree spec** (e.g. uploaded under a `.zip` name): lists as an "archive" whose entries are all 0 bytes; extracting creates empty files. Description extraction ignores an empty `FILE_ID.DIZ`.
**Not a disclosure risk.** mtree entries can name local files (`contents=/path`, or a bare path), but libarchive only reads them when the mtree `checkfs` option is enabled, which is off by default and never set by Synchronet. Verified via `Archive.list()`/`read()`/`extract()` and directly against libarchive 3.7.4 with absolute, relative, and bare-path specs: every entry has size 0 and no data.
## Proposed fix
In `check_archive_entry()` (`src/sbbs3/filedat.c`), reject `ARCHIVE_FORMAT_MTREE` the same way an uncompressed "raw" match is rejected, so the error is "Unrecognized archive format".
Optionally, when mtree is rejected and a decompression filter was applied, reopen the file with only the raw format enabled so a compressed text file lists as a single entry. Enumerating every format except mtree explicitly would also work, but would go stale as libarchive adds formats.
_Authored by Claude (Claude Code), on behalf of @rswindell_
--- SBBSecho 3.38-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)