Skip to content

Config: Fix crash loading a config without a mouse_type key - #7924

Merged
OBattler merged 1 commit into
86Box:masterfrom
MaxFreedomPollard:fix/config-mouse-type-null
Sep 11, 2026
Merged

OBattler merged 1 commit into
86Box:masterfrom
MaxFreedomPollard:fix/config-mouse-type-null

Conversation

@MaxFreedomPollard

Copy link
Copy Markdown
Contributor

Summary

86Box segfaults during startup when it loads a config file that has no mouse_type line under [Input devices], or no [Input devices] section at all. There is no message, the main window never appears. 86Box always writes mouse_type when it saves (src/config.c:3392), so configs it wrote itself are fine. What hits this is a hand written or hand trimmed config, one produced by another tool, or one truncated by an interrupted save.

The key is read with a NULL default at src/config.c:783. The mouse lookup right below it is guarded, and so is the tablet_type lookup at src/config.c:793, but the migration at src/config.c:790 passes the same pointer along unguarded:

    p = ini_section_get_string(cat, "mouse_type", NULL);
    if (p != NULL)
        mouse_type = mouse_get_from_internal_name(p);
    else
        mouse_type = 0;

    // Migration.
    if (tablet_get_from_internal_name(p) && mouse_type == 0)
        ini_section_set_string(cat, "tablet_type", p);

ini_section_get_string() returns its def argument both when the section is missing (src/utils/ini.c:903) and when the key is missing (src/utils/ini.c:907), so p is NULL in either case. tablet_get_from_internal_name() then calls strcmp() on it at src/device/mouse.c:736. The && evaluates the tablet lookup first, so the mouse_type == 0 test never gets the chance to short circuit it.

This patch moves the migration inside the existing if (p != NULL) branch. Configs that do have the key behave exactly as before, including writing tablet_type before the read two lines further down picks it up.

The migration was added in 10cdcda "Handle migrations" and touched again in 65accb5 "Fix migration", which corrected the value passed to ini_section_set_string() but not the guard.

I checked it with a small driver built against the real parser, src/utils/ini.c plus stubs for plat_fopen, rom_fopen and stricmp, running the block above on a config containing only a [Machine] section. Before the change it prints section = 0x0, mouse_type = 0x0, calling tablet_get_from_internal_name(0x0) and exits 139. After the change it prints survived, mouse_type = 0 and exits 0. A second driver whose [Input devices] section names a tablet device in mouse_type prints the same migrated tablet_type both before and after, so the migration itself is unchanged. clang -fsyntax-only -Wall -Wextra -std=gnu11 on src/config.c reports the same 238 warnings before and after, none of them on the touched lines, and the hunk is unchanged by clang-format with the repository .clang-format.

Checklist

  • I have tested my changes locally and validated that the functionality works as intended

References

The tablet migration added in 10cdcda passes the string returned by
ini_section_get_string(cat, "mouse_type", NULL) straight to
tablet_get_from_internal_name(), outside the NULL check two lines above
it. ini_section_get_string() returns the default when the key is missing
and also when the whole section is missing, so a config file without a
mouse_type line reaches the strcmp() in that lookup with a NULL pointer
and 86Box segfaults before the window appears. Fold the migration into
the existing non-NULL branch, which leaves it unchanged for every config
that does have the key.
@OBattler
OBattler merged commit a89cc55 into 86Box:master Sep 11, 2026
45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants