mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-09 02:06:54 +00:00
fix: out-of-bounds write migrating per-variant values when switching printers (#15456)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10091,6 +10091,10 @@ int DynamicPrintConfig::update_values_from_single_to_multi(DynamicPrintConfig& m
|
||||
|
||||
for (int index = 0; index < variant_count; index++)
|
||||
{
|
||||
//variant_count is the variant column width, src_opt the value array;
|
||||
//they disagree when the source was authored at a different width
|
||||
if (index >= (int)src_opt->values.size())
|
||||
break;
|
||||
if (opt->values[index] > src_opt->values[index])
|
||||
opt->values[index] = src_opt->values[index];
|
||||
}
|
||||
@@ -10108,6 +10112,8 @@ int DynamicPrintConfig::update_values_from_single_to_multi(DynamicPrintConfig& m
|
||||
|
||||
for (int index = 0; index < variant_count; index++)
|
||||
{
|
||||
if (index >= (int)src_opt->values.size())
|
||||
break;
|
||||
if (opt->values[index].value > src_opt->values[index].value)
|
||||
opt->values[index] = src_opt->values[index];
|
||||
}
|
||||
@@ -10302,6 +10308,10 @@ int DynamicPrintConfig::update_values_from_multi_to_multi(DynamicPrintConfig& ne
|
||||
|
||||
for(auto idx : variant_indices){
|
||||
assert(idx < old_count);
|
||||
//the counts come from the variant columns, the arrays from the options;
|
||||
//they disagree when a config was authored at a different variant width
|
||||
if (idx >= old_count || new_variant_index >= (int)opt->values.size())
|
||||
continue;
|
||||
if (old_values[idx] < opt->values[new_variant_index])
|
||||
opt->values[new_variant_index] = old_values[idx];
|
||||
}
|
||||
@@ -10332,6 +10342,10 @@ int DynamicPrintConfig::update_values_from_multi_to_multi(DynamicPrintConfig& ne
|
||||
|
||||
for(auto idx : variant_indices){
|
||||
assert(idx < old_count);
|
||||
//the counts come from the variant columns, the arrays from the options;
|
||||
//they disagree when a config was authored at a different variant width
|
||||
if (idx >= old_count || new_variant_index >= (int)opt->values.size())
|
||||
continue;
|
||||
if (old_values[idx] < opt->values[new_variant_index])
|
||||
opt->values[new_variant_index] = old_values[idx];
|
||||
}
|
||||
@@ -10362,6 +10376,8 @@ int DynamicPrintConfig::update_values_from_multi_to_multi(DynamicPrintConfig& ne
|
||||
|
||||
for(auto idx : variant_indices){
|
||||
assert(idx < old_count);
|
||||
if (idx >= old_count || new_variant_index >= (int)opt->values.size())
|
||||
continue;
|
||||
if (old_values[idx]) //enabled
|
||||
opt->values[new_variant_index] = old_values[idx];
|
||||
}
|
||||
@@ -10402,6 +10418,15 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector<st
|
||||
same_variant_indices.emplace_back(indices);
|
||||
}
|
||||
|
||||
//dst_values below is the destination PRINT preset's per-variant row, sized to its own
|
||||
//print_extruder_variant; dst_extruder_variants is the PRINTER's list. They disagree until
|
||||
//the print preset is re-selected, so size the row to the variant count before indexing it.
|
||||
const size_t dst_variant_count = dst_extruder_variants.size();
|
||||
if (dst_variant_count == 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: empty destination variant list")%__LINE__;
|
||||
return -1;
|
||||
}
|
||||
|
||||
t_config_option_keys keys = this->keys();
|
||||
for(auto& key : keys){
|
||||
if(key_sets.find(key) == key_sets.end())
|
||||
@@ -10417,7 +10442,13 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector<st
|
||||
{
|
||||
ConfigOptionFloatsNullable* opt = this->option<ConfigOptionFloatsNullable>(key);
|
||||
auto src_values = opt->values;
|
||||
auto dst_values = dst_config.option<ConfigOptionFloatsNullable>(key) ->values;
|
||||
const auto* dst_opt = dst_config.option<ConfigOptionFloatsNullable>(key);
|
||||
if(!dst_opt){
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: %2% missing from destination config")%__LINE__%key;
|
||||
break;
|
||||
}
|
||||
auto dst_values = dst_opt->values;
|
||||
dst_values.resize(dst_variant_count, ConfigOptionFloatsNullable::nil_value());
|
||||
for(size_t dst_idx =0; dst_idx < same_variant_indices.size(); ++dst_idx){
|
||||
auto& indices = same_variant_indices[dst_idx];
|
||||
if(indices.empty())
|
||||
@@ -10425,7 +10456,7 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector<st
|
||||
bool has_value = false;
|
||||
double target_value = std::numeric_limits<double>::max();
|
||||
for(auto idx : indices){
|
||||
if(opt && idx < opt->values.size() && !opt->is_nil(idx)){
|
||||
if(idx < (int)opt->values.size() && !opt->is_nil(idx)){
|
||||
has_value = true;
|
||||
target_value = std::min(target_value, src_values[idx]);
|
||||
}
|
||||
@@ -10441,7 +10472,13 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector<st
|
||||
{
|
||||
ConfigOptionFloatsOrPercentsNullable* opt = this->option<ConfigOptionFloatsOrPercentsNullable>(key);
|
||||
auto src_values = opt->values;
|
||||
auto dst_values = dst_config.option<ConfigOptionFloatsOrPercentsNullable>(key) ->values;
|
||||
const auto* dst_opt = dst_config.option<ConfigOptionFloatsOrPercentsNullable>(key);
|
||||
if(!dst_opt){
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: %2% missing from destination config")%__LINE__%key;
|
||||
break;
|
||||
}
|
||||
auto dst_values = dst_opt->values;
|
||||
dst_values.resize(dst_variant_count, ConfigOptionFloatsOrPercentsNullable::nil_value());
|
||||
for(size_t dst_idx =0; dst_idx < same_variant_indices.size(); ++dst_idx){
|
||||
auto& indices = same_variant_indices[dst_idx];
|
||||
if(indices.empty())
|
||||
@@ -10449,7 +10486,7 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector<st
|
||||
bool has_value = false;
|
||||
FloatOrPercent target_value{9999.f, true};
|
||||
for(auto idx : indices){
|
||||
if(opt && !opt->is_nil(idx)){
|
||||
if(idx < (int)opt->values.size() && !opt->is_nil(idx)){
|
||||
has_value = true;
|
||||
target_value = src_values[idx].value < target_value.value ? src_values[idx] : target_value;
|
||||
}
|
||||
@@ -10465,15 +10502,21 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector<st
|
||||
{
|
||||
ConfigOptionBoolsNullable* opt = this->option<ConfigOptionBoolsNullable>(key);
|
||||
auto src_values = opt->values;
|
||||
auto dst_values = dst_config.option<ConfigOptionBoolsNullable>(key) ->values;
|
||||
const auto* dst_opt = dst_config.option<ConfigOptionBoolsNullable>(key);
|
||||
if(!dst_opt){
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: %2% missing from destination config")%__LINE__%key;
|
||||
break;
|
||||
}
|
||||
auto dst_values = dst_opt->values;
|
||||
dst_values.resize(dst_variant_count, ConfigOptionBoolsNullable::nil_value());
|
||||
for(size_t dst_idx =0; dst_idx < same_variant_indices.size(); ++dst_idx){
|
||||
auto indices = same_variant_indices[dst_idx];
|
||||
if(indices.empty())
|
||||
continue;
|
||||
bool has_value = false;
|
||||
bool target_value;
|
||||
bool target_value = false;
|
||||
for(auto idx : indices){
|
||||
if(opt && !opt->is_nil(idx)){
|
||||
if(idx < (int)opt->values.size() && !opt->is_nil(idx)){
|
||||
has_value = true;
|
||||
target_value = src_values[idx];
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user