fix: crash on Multimaterial tab for all printers (Windows-only)

The "Pre-slice warnings" line in the IDEX/IQEX Configuration section
was a widget-only line (no options) with full_width left at the default
of 0. activate_line() only skips the option_set.front() call when
full_width=1; without it, the code falls through to:

    bool is_legend_line = option_set.front().opt.gui_type == ...

Calling front() on an empty std::vector is undefined behavior. On
Windows/MSVC release builds this dereferences a null pointer and reads
at offset 0x30 (where ConfigOptionDef::gui_type lands), producing an
ACCESS_VIOLATION at 0x30. On Linux/GCC the same UB happens to be
harmless, so the crash is Windows-only and cannot be reproduced on
Linux.

Fix: set line.full_width = 1, matching the pattern used by the "Modes"
(IMEXModesCtrl) line. This takes the early-return widget path in both
append_line and activate_line, bypassing option_set.front() entirely.

Reported by tester: crash on clicking Multimaterial tab with any
printer (K3D VOSTOK confirmed), build af59501f.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Clifford Garwood
2026-04-15 16:45:25 -04:00
co-authored by Claude Sonnet 4.6
parent af59501f4a
commit 2cfdddf8b0
+4
View File
@@ -5371,10 +5371,14 @@ if (is_marlin_flavor)
optgroup->append_single_option_line("imex_carriage_margin");
{
// Toggle for pre-slice IMEX safety warnings (stored in app_config, not printer profile)
// full_width = 1 is required: widget-only lines (no options) must take the full-width
// path in activate_line/append_line to avoid option_set.front() on an empty vector,
// which crashes on Windows release builds (ACCESS_VIOLATION at 0x30).
auto line = Line{ L("Pre-slice warnings"), L("Show a warning dialog before slicing if IDEX/IQEX parallel mode "
"concerns are detected (bed temperature conflicts, filament type "
"mismatches, multi-material conflicts). Can be suppressed from the "
"dialog itself. Re-enable here if suppressed accidentally.") };
line.full_width = 1;
line.widget = [](wxWindow* parent) -> wxSizer* {
auto* cb = new wxCheckBox(parent, wxID_ANY, wxEmptyString);
bool enabled = wxGetApp().app_config->get("imex_pre_slice_warnings") != "false";