https://gitlab.synchro.net/main/sbbs/-/commit/ff8e663eac35532c2c7c7f3e
Added Files:
src/smblib/tests/smballoctest.c
Modified Files:
docs/v322_new.md src/sbbs3/chksmb.c src/smblib/smballoc.c smblib.c src/smblib/tests/GNUmakefile
Log Message:
SMB: reference-count message data over its whole span
A message's data is allocated as one contiguous span, and smbutil pack references shared data over that span, but smb_freemsg_dfields() and smb_incmsg_dfields() adjusted the counts one data field at a time: each
field from the block its offset falls in, for as many blocks as its own
length rounds up to. When the body ends inside a block and a tail
follows, that block was adjusted twice and the block the tail spills
into not at all. So:
* deleting a message never freed the tail's spill block (a leak, which
a pack reclaims);
* after a pack re-referenced shared data by span, deleting one copy
freed blocks the other copies still used;
* fixsmb, rebuilding the .sda from zero per field, left the spill block
of every live message with a tail counted 0, so the next self-packing
allocation could overwrite the end of that message.
Signature tails make this common for mail: savemsg() stores everything
after a "-- " line as a tail, and mail to several local recipients
shares one copy of the data.
Both functions now adjust the whole span in one call, and fixsmb, which
uses smb_incmsg_dfields(), rebuilds by span. smb_getmsgdatlen() returns
the extent of the data (the end of the furthest field) rather than the
sum of the field lengths; the two are equal for all data written today.
chksmb checked only the blocks the per-field arithmetic reached, so it
could not see a spill block marked free. It now checks every block of
the span, and reports those as misallocated active data blocks, which
fixsmb repairs.
Add smballoctest to src/smblib/tests.
Fixes #1253
Co-Authored-By: Claude Opus 5.5 <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net