• Archive class / file-base listings can't open bare .gz (and other sing

    From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Sun Oct 4 08:29:11 2026
    open https://gitlab.synchro.net/main/sbbs/-/work_items/1278

    ## Summary

    Bare single-file compressed files (`.gz`, and by the same mechanism `.bz2`, `.xz`, `.zst`, `.lz4`, ...) can't be opened by the `Archive` JS class or the file-base archive code, even after the sysop adds the extension to the supported archive types in SCFG. libarchive can read them, but only when the "raw" format is enabled, and Synchronet never enables it.

    Reported by Nelgin (EOTLBBS) on DOVE-Net Synchronet Discussion ("Adding supported_formats to Archive", Oct 3 2026):

    ```
    $ jsexec -n -r 'Archive.supported_formats.forEach(function(f){ print(f); })' zip
    7z
    tgz
    gz
    $ jsexec -n archive read /var/log/sbbs/web.sbbs.log.1.gz
    !JavaScript /sbbs/exec/archive.js line 49: Error: archive_read_open_filename() returned -30: Unrecognized archive format
    ```

    ## Cause

    Every libarchive read site enables `archive_read_support_filter_all()` + `archive_read_support_format_all()` only:

    - `src/sbbs3/js_archive.cpp` (two sites: list and extract/read)
    - `src/sbbs3/filedat.c` (two sites)

    `archive_read_support_format_all()` deliberately excludes the "raw" (and "empty") formats, because "raw" matches any input. The libarchive README says decompression without archiving requires explicitly selecting "raw".

    Verified against libarchive 3.7.4 with a small test program:

    | enabled | `t.txt.gz` | `t.tgz` |
    |---|---|---|
    | filter_all + format_all | `-30 Unrecognized archive format` | GNU tar |
    | + `archive_read_support_format_raw()` | 1 entry `t.txt` (name from the gzip header), format=raw, filter=gzip, data decompressed OK, size not set | still GNU tar ("raw" only wins when nothing else matches) |

    ## Proposed fix

    Enable `archive_read_support_format_raw()` at each read site, but **only accept a raw result when a decompression filter was actually applied**. Otherwise every non-archive file (`.txt`, `.jpg`, ...) would "open" as a one-entry archive, and the file-base archive listing would treat all files as archives. After `archive_read_next_header()`, something like:

    ```c
    if (archive_format(ar) == ARCHIVE_FORMAT_RAW
    && archive_filter_code(ar, 0) == ARCHIVE_FILTER_NONE)
    /* not compressed: treat as unrecognized, as before */
    ```

    Other details to handle:

    - The entry name comes from the gzip header when present; otherwise libarchive reports `data`. Deriving the name from the filename minus its compression extension would be friendlier.
    - The entry size isn't known until the data is decompressed (`archive_entry_size_is_set()` is 0), so listings have to cope with an unknown size.
    - Should a bare `.gz` be a valid "archive" type in SCFG at all, or should this be handled implicitly? Today SCFG accepts `gz` in the list and then it always fails.

    See also #453 (bare `.bz2` hang in libarchive on Windows).

    - *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.38-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell@1:103/705 to GitLab note in main/sbbs on Fri Oct 16 21:08:06 2026
    https://gitlab.synchro.net/main/sbbs/-/work_items/1278#note_10630

    Fixed on master (local commits, not yet pushed):

    **Reading bare compressed files.** All libarchive read sites now enable the "raw" format, but accept a raw result only when a decompression filter was applied, so an uncompressed non-archive is still "Unrecognized archive format". A bare `.gz`, `.bz2`, `.xz` or `.zst` file reads as a one-entry archive named after the file minus its compression extension (`log.txt.gz` -> `log.txt`), not the gzip header's optional stored name, which may contain a path. `Archive.list()` decompresses the data to report the size, since libarchive doesn't know it in advance. Tested: list, hashed list, read and extract all match the original data; `.tgz`/`.zip` behave as before.

    `filecontents_lib.js` caches "unreadable" verdicts, so `EXTRACTORS` was bumped to 2: `.gz` files previously recorded as unreadable get listed on their next view. Hosts sharing file areas should all run the new build before then, or an older build re-records the failure under the new version. `ARCHIVE_TYPES` there now also includes `xz` and `zst` (it already had `gz` and `bz2`).

    **Should `gz` be a valid Supported Archive Format in SCFG?** No. That list is the set of types Synchronet *creates* (QWK/REP packets and temporary download archives), and users can pick any entry as their QWK packet type. Only `zip`, `7z`, `tgz` and `tbz` can be created, and a bare `.gz` holds a single file, so it could never hold a QWK packet. Listing `gz` offered users a packet type that always failed to build. Reading and viewing archives never depended on this list.

    SCFG now removes any type that can't be created, tells the sysop which, and saves the cleaned list, so an existing `gz` entry is dropped the next time the field is visited. The help text no longer suggests adding other libarchive formats, and the File Options overview no longer claims the list covers mail attachments and the testable/extractable file types.

    No SCFG change is needed to view `.gz` files: with the fix above they list in the web file index and the terminal viewer as-is.

    Two older issues found while testing, not changed here: a text file made only of single-word lines (e.g. `seq` output) is claimed by libarchive's mtree reader and fails with "Missing type keyword in mtree specification", compressed or not; and the `Archive.type` getter returns the error string "archive_read_next_header returned 1: (null)" for an archive with no entries instead of null.

    _Authored by Claude (Claude Code), on behalf of @rswindell_
    --- SBBSecho 3.38-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Fri Oct 16 21:19:05 2026
    close https://gitlab.synchro.net/main/sbbs/-/work_items/1278
    --- SBBSecho 3.38-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)