From 7b029f6f9d45ff2e3c7ed09a5abbe5bfeceb1aed Mon Sep 17 00:00:00 2001 From: Hanif Koh Date: Tue, 1 Sep 2026 12:09:29 +0800 Subject: [PATCH] Move empty-vector guard into DynamicPrintConfig::get_filament_type --- src/OrcaSlicer.cpp | 18 ++++-------------- src/libslic3r/PrintConfig.cpp | 10 +++++++++- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 918c23112d..c0e811454c 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -6497,7 +6497,6 @@ int CLI::run(int argc, char **argv) bool need_create_thumbnail_group = false, need_create_no_light_group = false, need_create_top_group = false; // get type and color for platedata - auto* filament_types = dynamic_cast(m_print_config.option("filament_type")); const ConfigOptionStrings* filament_color = dynamic_cast(m_print_config.option("filament_colour")); auto* filament_id = dynamic_cast(m_print_config.option("filament_ids")); const ConfigOptionFloats* nozzle_diameter_option = dynamic_cast(m_print_config.option("nozzle_diameter")); @@ -6516,20 +6515,11 @@ int CLI::run(int argc, char **argv) plate_data->nozzle_diameters = nozzle_diameter_str; for (auto it = plate_data->slice_filaments_info.begin(); it != plate_data->slice_filaments_info.end(); it++) { - // ConfigOptionVector::get_at() falls back to values.front() when the index is out of - // range, but that is undefined behavior when values is empty outright (e.g. filament_ids - // is never populated on a from-scratch slice with no --load-filaments) - guard every - // get_at() here on the vector actually having an entry at it->id before calling it. - bool valid_id = it->id >= 0; + // get_at() on an empty vector option is UB - these can be unpopulated on a from-scratch slice std::string display_filament_type; - if (valid_id && filament_types && static_cast(it->id) < filament_types->values.size()) - it->type = m_print_config.get_filament_type(display_filament_type, it->id); - it->color = (valid_id && filament_color && static_cast(it->id) < filament_color->values.size()) ? - filament_color->get_at(it->id) : - "#FFFFFF"; - it->filament_id = (valid_id && filament_id && static_cast(it->id) < filament_id->values.size()) ? - filament_id->get_at(it->id) : - ""; + it->type = m_print_config.get_filament_type(display_filament_type, it->id); + it->color = (filament_color && !filament_color->values.empty()) ? filament_color->get_at(it->id) : "#FFFFFF"; + it->filament_id = (filament_id && !filament_id->values.empty()) ? filament_id->get_at(it->id) : ""; } if (!plate_data->plate_thumbnail.is_valid()) { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 2a4eb8d7a7..c33de031cf 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -9866,7 +9866,15 @@ std::string DynamicPrintConfig::get_filament_type(std::string &displayed_filamen auto* filament_type = dynamic_cast(this->option("filament_type")); auto* filament_is_support = dynamic_cast(this->option("filament_is_support")); - if (!filament_type) + // get_at() on an empty vector option is undefined behavior (.front() of an empty vector), + // and e.g. filament_id is never populated on a CLI from-scratch slice - treat an empty + // option the same as a missing one. + if (filament_id && filament_id->values.empty()) + filament_id = nullptr; + if (filament_is_support && filament_is_support->values.empty()) + filament_is_support = nullptr; + + if (!filament_type || filament_type->values.empty()) return ""; if (!filament_is_support) {