• src/xpdev/ini_file.c

    From Rob Swindell (on Windows 11)@1:103/705 to Git commit to main/sbbs/master on Wednesday, May 27, 2026 22:24:10
    https://gitlab.synchro.net/main/sbbs/-/commit/e3a18a8eeac56fb1577f60dc
    Modified Files:
    src/xpdev/ini_file.c
    Log Message:
    xpdev: initialize p in iniParseSections() to silence /sdl C4703

    CI job 1507910 (windows-x86 [sbbs], commit 311ed074) failed with a hard
    C4703 ("potentially uninitialized local pointer variable 'p' used") at ini_file.c:1709 from sbbsexec.vcxproj, which uses the VS2017 toolset
    (MSVC 14.16) and /sdl (which elevates C4703 to error). The use is
    actually safe — the preceding `for (i = 0; list[i] != NULL; ++i)`
    loop runs at least once (list[0] != NULL was just checked) and sets
    p on every iteration — but the older toolset's per-TU data-flow can't
    see that proof. Whole-program optimization could; 311ed074 disabled
    WPO for Release|Win32, removing the cover.

    The faulty data-flow chain (early return + extended use of p outside
    the discovery loop) was introduced in 48edf261f0; initializing p at
    its declaration silences the warning and makes the invariant explicit
    at zero runtime cost.
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell (on Debian Linux)@1:103/705 to Git commit to main/sbbs/master on Monday, June 22, 2026 18:22:50
    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>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)