From 044a4547223998f3169889b03cc47c62245039e9 Mon Sep 17 00:00:00 2001 From: Stefan Siebert <102414579+stefan-siebert@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:48:08 +0200 Subject: [PATCH] Fix crash on startup when no configuration exists yet InitShellIconOverlays() copies SALAMANDER_ROOT_REG into the overlay diagnostics header, but that pointer is NULL whenever FindLatestConfiguration() didn't load a configuration - a first run on a clean machine, or an import offer the user declined. It only gets set to SalamanderConfigurationRoots[0] later in the startup sequence, after this call. lstrcpyn is remapped to _sal_lstrcpynA in common/lstrfix.h so that NULL faults instead of being swallowed, so this is an access violation reading 0x0 about 140 ms into startup. It happens before any configuration is written, so it repeats on every launch: 1.0.24 can't start at all on a machine that has no Salamander configuration yet. Guard the copy the way every other reader of SALAMANDER_ROOT_REG already does. An empty config root in the report is the right answer for "no configuration loaded". --- src/shiconov.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/shiconov.cpp b/src/shiconov.cpp index 3ff4763fb..0489c9cba 100644 --- a/src/shiconov.cpp +++ b/src/shiconov.cpp @@ -405,7 +405,14 @@ void InitShellIconOverlays() ShellOverlayDiag.Header.IconSizes[2] = IconSizes[ICONSIZE_48]; ShellOverlayDiag.Header.SystemDpi = (UINT)SystemDPI; ShellOverlayDiag.Header.EnableCustomIconOverlays = Configuration.EnableCustomIconOverlays != FALSE; - lstrcpynA(ShellOverlayDiag.Header.ConfigRoot, SALAMANDER_ROOT_REG, + // SALAMANDER_ROOT_REG is still NULL here whenever no configuration was found: + // FindLatestConfiguration() clears it up front and only assigns a root when a key with + // a "Configuration" subkey exists, and the fallback to SalamanderConfigurationRoots[0] + // happens later in the startup sequence than this call. Sally's lstrcpyn is the + // deliberately crashing variant from lstrfix.h, so NULL is an access violation here, + // not a truncated string. Every other reader of SALAMANDER_ROOT_REG guards for NULL. + lstrcpynA(ShellOverlayDiag.Header.ConfigRoot, + SALAMANDER_ROOT_REG != NULL ? SALAMANDER_ROOT_REG : "", (int)sizeof(ShellOverlayDiag.Header.ConfigRoot)); if (Configuration.DisabledCustomIconOverlays != NULL) {