• Editing a file's extended description loses or misplaces its auxdata (

    From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Tue Sep 29 15:49:36 2026
    open https://gitlab.synchro.net/main/sbbs/-/work_items/1269

    ## Summary

    Editing a file's extended description from the terminal server (`sbbs_t::editfileinfo()`, reached from the file lister and the file viewer) replaces the record's data through `sbbs_t::editmsg()`, which only handles the message layout. A file record keeps its `auxdata` (including the stored archive content listing) in a `TEXT_TAIL` data field, and `editmsg()` loses it:

    1. **Record with an extended description and auxdata** (body + tail): the old
    body and tail are both freed, only the new description is written, and the
    tail's data field is left in the header unchanged. Its offset is relative to
    the header's data offset, which now points at the new allocation, so the
    tail refers to whatever follows the new description: unallocated blocks or
    another record's data.
    2. **Record with auxdata but no extended description** (tail only): the tail is
    freed and its data field is overwritten with the new description. The
    auxdata is silently gone.

    ## Mechanism

    `src/sbbs3/writemsg.cpp`, `sbbs_t::editmsg()` (line 1699):

    * `is_msg` is false for a file record (`SMB_MSG_TYPE_FILE`), so only the body
    is exported to the editor (`GETMSGTXT_BODY_ONLY`).
    * `smb_freemsg_dfields(smb, msg, 1)` then frees **every** data field, tail
    included.
    * `dfield[0]` is rewritten as a single `TEXT_BODY` of the new length at
    offset 0 (line 1747).
    * The loop that clears the remaining data fields to `UNUSED` runs only
    `if (is_msg)` (line 1750), so for a file record `dfield[1]` keeps its
    `TEXT_TAIL` type, old relative offset and old length.
    * New data is allocated, `msg->hdr.offset` is updated, and the header is
    written with `smb_putmsghdr()`.

    `editfileinfo()` (`src/sbbs3/file.cpp`, the `editmsg(&smb, f)` call at line 346) then calls `updatefile()`, which is `smb_updatemsg()`: a header rewrite from the same in-memory data fields, so nothing repairs the tail afterwards.

    For messages the same function behaves correctly: the tail is exported to the editor along with the body, and the extra data fields are cleared.

    ## Exposure

    Only the extended-description editor in the terminal server calls `editmsg()` on a file record (`listfile.cpp:882`, `viewfile.cpp:68` -> `editfileinfo()`). JavaScript `FileBase.update()` goes through `smb_updatefile()`, which writes extdesc and auxdata together and is not affected.

    A read-only scan of the file bases on one production system (1794 bases, 147,375 live records, 66,583 with a `TEXT_TAIL`, 19,356 of those tail-only) found **no** record whose tail offset differs from where its body ends, so
    case 1 has not happened there. Case 2 leaves no trace in the header and cannot be detected after the fact.

    Found by reading the code; not yet reproduced in a running terminal session.

    ## Suggested fix

    Route file records through `smb_updatefile()` instead of rewriting the data in `editmsg()`: take the edited text as the new extdesc and pass the record's existing auxdata unchanged. `smb_updatefile()` already writes both fields, allocates before freeing, and handles the tail-only and body-only layouts. The record must be loaded with auxdata (`file_detail_auxdata`) for that to work.

    Related: #1252 (the free-before-allocate ordering in `editmsg()`), #1253 (how data fields are reference-counted), #1247 (archive listings in auxdata).

    -- *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Tue Sep 29 17:07:33 2026
    close https://gitlab.synchro.net/main/sbbs/-/work_items/1269
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)