https://gitlab.synchro.net/main/sbbs/-/commit/4d5604ba4099789799955488
Modified Files:
src/xpdev/ini_file.c
Log Message:
xpdev: fix iniSetString/iniGetSection misfiling keys in empty sections
When an ini section's header exists but the section is empty (immediately followed by another section header, or EOF), section_start() returned the
end of the list, so iniSetString()/iniSetValue() inserted new keys at the
end of the file -- under the last section -- instead of into the intended (empty) section. The misfiled keys then couldn't be read back via iniGetString(section, key), and repeated rewrites accumulated duplicates (GitLab #1168).
Root-cause the special case away: find_section() now returns the index of
the next section header (or the list terminator) for an empty section,
which is both the correct stop-point for read loops and the correct
insertion point for new keys. section_start() is removed (it collapsed to
an identity).
That change required guarding iniGetSection(): it unconditionally pushed list[i] and only worked before because find_section() returned the NULL terminator for an empty section. It now skips the push when list[i] is a section header, so an empty section yields no keys instead of bleeding the following section's header and keys into the result. This also fixes a pre-existing latent bug: iniGetSection(ROOT) on a file with no root-level
keys returned the first named section's contents -- which corrupted iniSortSections(list, NULL, ...) output (reachable from filedat.c's batch_list_sort(), duplicating the first entry of a no-root batch list).
Adds an in-memory regression suite under #ifdef INI_FILE_TEST (run when the test binary is invoked with no file arguments): 6 checks covering the
#1168 misfile, the empty-section read guard, and the empty-root case. The
suite reports 3 failures against the unfixed code and 0 against the fix.
Co-Authored-By: Claude Opus 4.8 <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net