mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-16 21:42:43 +00:00
fix: guard per-filament array reads against short config arrays (#14789)
* fix: guard H2C per-filament array reads against short config arrays The H2C tool-ordering, wipe-tower, and g-code export paths index per-filament config arrays by filament/tool id. A config with fewer entries than the filament count (partial or legacy projects, minimal test configs) makes these reads run past the end of the vector: silent under a normal STL, but UB that aborts under the flatpak build's bounds-checked STL (_GLIBCXX_ASSERTIONS). Route the reads through the existing clamping accessors (get_at, get_filament_category, is_in_same_extruder) and add a small clamp helper for filament_change_length. The guards are no-ops when the arrays are sized to the filament count, so correctly specified configs are unaffected. * fix: size the grouping context's filament_info to the filament count build_filament_group_context built model_info.filament_info by walking filament_type, so a config whose filament_type is shorter than the filament count produced a short vector. FilamentGroup indexes filament_info by filament id, so clamping the individual reads only moved the out-of-bounds access downstream. Loop to filament_nums and read all three fields through get_at, and drop filament_ids entries past the filament count, since the grouping code pairs filament_ids and filament_info by position. Adds a regression test with four filaments and one-entry filament_type / filament_is_support. Without the fix it throws bad_alloc from copying a garbage std::string read past the end. * fix: guard the carousel nozzle-change length reads too The carousel branch added in b90ac13d86/b0dddb4648 reads m_filaments_change_length by tool id without a bounds check, the same pattern this branch already routed through filament_change_length_at a few lines above in both plan_toolchange and plan_tower_new. * fix: guard WipeTower per-filament array reads against short config arrays The BambuStudio WipeTower sync reintroduced raw per-filament array indexing that reads out of bounds when a config leaves an array shorter than the filament count: m_physical_extruder_map in format_line_M104/M109 (indexed even when empty), and m_filament_categories in get_wall_skip_points and get_wall_filament_for_all_layer. Silent on a normal STL, a hard abort under the bounds-checked STL the Flatpak build uses. Bounds-check the physical extruder map before indexing (omitting the T token, as the existing -1 path already does), and route the two raw m_filament_categories reads through the clamping get_filament_category() accessor the surrounding code already uses. No change for correctly-sized configs.
This commit is contained in:
@@ -1488,10 +1488,10 @@ static FilamentGroupContext build_filament_group_context(
|
||||
|
||||
auto machine_filament_info = build_machine_filaments(print->get_extruder_filament_info(), extruder_ams_counts, ignore_ext_filament);
|
||||
|
||||
std::vector<std::string> filament_types = print_config.filament_type.values;
|
||||
std::vector<std::string> filament_colours = print_config.filament_colour.values;
|
||||
std::vector<unsigned char> filament_is_support = print_config.filament_is_support.values;
|
||||
std::vector<std::string> filament_ids = print_config.filament_ids.values;
|
||||
// The grouping code walks filament_ids and indexes filament_info by the same position.
|
||||
std::vector<std::string> filament_ids = print_config.filament_ids.values;
|
||||
if (filament_ids.size() > filament_nums)
|
||||
filament_ids.resize(filament_nums);
|
||||
|
||||
FGMode fg_mode = mode == FilamentMapMode::fmmAutoForMatch ? FGMode::MatchMode : FGMode::FlushMode;
|
||||
context.model_info.flush_matrix = std::move(nozzle_flush_mtx);
|
||||
@@ -1500,11 +1500,14 @@ static FilamentGroupContext build_filament_group_context(
|
||||
context.model_info.filament_ids = filament_ids;
|
||||
context.model_info.unprintable_volumes = unprintable_volumes;
|
||||
|
||||
for (size_t idx = 0; idx < filament_types.size(); ++idx) {
|
||||
// Consumers index filament_info by filament id, so it must span the filament count: a partial
|
||||
// or legacy config can leave any of these arrays short, and get_at clamps.
|
||||
context.model_info.filament_info.reserve(filament_nums);
|
||||
for (size_t idx = 0; idx < filament_nums; ++idx) {
|
||||
FilamentGroupUtils::FilamentInfo info;
|
||||
info.color = filament_colours[idx];
|
||||
info.type = filament_types[idx];
|
||||
info.is_support = filament_is_support[idx];
|
||||
info.color = print_config.filament_colour.get_at(idx);
|
||||
info.type = print_config.filament_type.get_at(idx);
|
||||
info.is_support = print_config.filament_is_support.get_at(idx);
|
||||
context.model_info.filament_info.emplace_back(std::move(info));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user