mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-11 01:41:03 +00:00
update_values_from_multi_to_multi_2 iterates the destination PRINTER's variant list while writing into a row taken from the destination PRINT preset. Those two lengths are maintained independently -- print_extruder_variant against printer_extruder_variant -- and Tab::load_current_preset() runs the migration before the print preset is re-selected for the new printer. Opening a project saved on a single-variant printer and switching to a seven-variant one therefore wrote six elements past the end of a one-element vector. The corruption stays silent until the next allocation, so the abort surfaces somewhere unrelated and the backtrace points at innocent code. Size the row to the variant count before indexing it. Every write is then in range, and the result carries one value per destination variant, which is what the callers consume. Pad with nil rather than a copied value: set_to_index() skips nil entries, so a variant the object has no opinion about keeps tracking the print preset instead of being pinned to another variant's number. The same shape -- a count from one array indexing another -- appears twice more in this file. update_values_from_multi_to_multi has three of these writes protected only by assert(idx < old_count), and NDEBUG is defined for every non-Debug configuration, so those guards are absent from shipping builds. update_values_from_single_to_multi has the read half. Both are bounded here; leaving them would fix one third of one defect. Source reads are bounded too. is_nil(size_t) indexes values[idx] without checking, so an index past the end was undefined behaviour on that side as well. Where the row already matches the variant list -- every case that was not corrupting the heap -- the resize is a no-op and the output is unchanged. Fixes #15455 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>