mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-09 10:16:50 +00:00
[CLI]: CLI Crash Guards (#15477)
# Description <!-- > Please provide a summary of the changes made in this PR. Include details such as: > * What issue does this PR address or fix? > * What new features or enhancements does this PR introduce? > * Are there any breaking changes or dependencies that need to be considered? --> Part 1 of 3 of the CLI-mode bug sweep, split out of #15452 per review feedback there. This PR contains the crash fixes. ## Fixes - **`--outputdir`/`--datadir` with a missing parent directory aborted** via unguarded `create_directory`. Directories are now created recursively, with a graceful early exit and a specific error message if creation fails. - **`--slice` + `--export-3mf` segfaulted on a from-scratch slice**: `ConfigOptionVector::get_at()` on an empty vector is `.front()` of an empty vector (UB). Guards added for `filament_color`/`filament_id` at the CLI call site, and inside `DynamicPrintConfig::get_filament_type` for `filament_type`/`filament_is_support`/`filament_id`. Only *empty* vectors are treated as missing — the existing clamp-to-front behavior for merely out-of-range indices is preserved, so GUI callers are unaffected. - **OOB heap write from stale `filament_self_index` on `--load-filaments`** (fixes #14181): a 3MF carrying more `filament_self_index` entries than loaded filaments wrote past the end of `old_variant_counts`. The guard validates both bounds — entries `> filament_count` *and* non-positive entries (`< 1`), since a single `0` in an otherwise-valid array indexes `old_variant_counts[-1]`. - **Wrong printable-area check** for non-rectangular beds: use the printable area's bounding box instead of a naive vertex calculation (fixes #15363). - **`nozzle_height` and `align_center` were not read into the arrange config** in CLI mode. # Screenshots/Recordings/Graphs <!-- > Please attach relevant screenshots to showcase the UI changes. > Please attach images that can help explain the changes. --> ## Tests <!-- > Please describe the tests that you have conducted to verify the changes made in this PR. --> - Repro'd each crash on CLI before the fix; all resolved after. - `tests/libslic3r` suite passes; full binary builds clean on Linux. - Added `get_filament_type` unit tests <!-- > A guide for users on how to download the artifacts from this PR. --> [How to Download Pull Requests Artifacts for Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
This commit is contained in:
@@ -856,19 +856,19 @@ TEST_CASE("read_cli rejects an invalid boolean value", "[Config]") {
|
||||
|
||||
TEST_CASE("read_cli accepts the common spellings of a boolean value", "[Config]") {
|
||||
const auto [text, expected] = GENERATE(table<const char*, bool>({
|
||||
{"--reduce-crossing-wall=1", true },
|
||||
{"--reduce-crossing-wall=true", true },
|
||||
{"--reduce-crossing-wall=Yes", true },
|
||||
{"--reduce-crossing-wall=on", true },
|
||||
{"--reduce-crossing-wall=enabled", true },
|
||||
{"--reduce-crossing-wall=TRUE", true },
|
||||
{"--reduce-crossing-wall=oN", true },
|
||||
{"--reduce-crossing-wall=0", false},
|
||||
{"--reduce-crossing-wall=false", false},
|
||||
{"--reduce-crossing-wall=No", false},
|
||||
{"--reduce-crossing-wall=off", false},
|
||||
{"--reduce-crossing-wall=1", true},
|
||||
{"--reduce-crossing-wall=true", true},
|
||||
{"--reduce-crossing-wall=Yes", true},
|
||||
{"--reduce-crossing-wall=on", true},
|
||||
{"--reduce-crossing-wall=enabled", true},
|
||||
{"--reduce-crossing-wall=TRUE", true},
|
||||
{"--reduce-crossing-wall=oN", true},
|
||||
{"--reduce-crossing-wall=0", false},
|
||||
{"--reduce-crossing-wall=false", false},
|
||||
{"--reduce-crossing-wall=No", false},
|
||||
{"--reduce-crossing-wall=off", false},
|
||||
{"--reduce-crossing-wall=disabled", false},
|
||||
{"--reduce-crossing-wall=FALSE", false},
|
||||
{"--reduce-crossing-wall=FALSE", false},
|
||||
{"--reduce-crossing-wall=DiSaBlEd", false},
|
||||
}));
|
||||
|
||||
@@ -1051,3 +1051,43 @@ TEST_CASE("read_cli accepts nil entries for a nullable vector option", "[Config]
|
||||
REQUIRE_FALSE(opt->is_nil(1));
|
||||
REQUIRE_THAT(opt->values[1], Catch::Matchers::WithinAbs(2.5, 1e-9));
|
||||
}
|
||||
|
||||
// get_at() returns values.front() for an out-of-range index, so calling it on an empty vector
|
||||
// option is UB. filament_id and filament_is_support are unpopulated on a CLI from-scratch slice.
|
||||
TEST_CASE("get_filament_type treats empty vector options as absent", "[Config][Filament]")
|
||||
{
|
||||
DynamicPrintConfig config;
|
||||
std::string displayed;
|
||||
|
||||
SECTION("an empty filament_type yields no type at all")
|
||||
{
|
||||
config.set_key_value("filament_type", new ConfigOptionStrings());
|
||||
REQUIRE(config.get_filament_type(displayed, 0) == "");
|
||||
}
|
||||
|
||||
SECTION("an empty filament_is_support falls back to the plain filament type")
|
||||
{
|
||||
config.set_key_value("filament_type", new ConfigOptionStrings({"PETG"}));
|
||||
config.set_key_value("filament_is_support", new ConfigOptionBools());
|
||||
REQUIRE(config.get_filament_type(displayed, 0) == "PETG");
|
||||
REQUIRE(displayed == "PETG");
|
||||
}
|
||||
|
||||
SECTION("a support filament with an empty filament_id resolves from the type alone")
|
||||
{
|
||||
config.set_key_value("filament_type", new ConfigOptionStrings({"PLA"}));
|
||||
config.set_key_value("filament_is_support", new ConfigOptionBools({true}));
|
||||
config.set_key_value("filament_id", new ConfigOptionStrings());
|
||||
REQUIRE(config.get_filament_type(displayed, 0) == "PLA-S");
|
||||
REQUIRE(displayed == "Sup.PLA");
|
||||
}
|
||||
|
||||
SECTION("a populated filament_id still selects the support type by id")
|
||||
{
|
||||
config.set_key_value("filament_type", new ConfigOptionStrings({"PETG"}));
|
||||
config.set_key_value("filament_is_support", new ConfigOptionBools({true}));
|
||||
config.set_key_value("filament_id", new ConfigOptionStrings({"GFS00"}));
|
||||
REQUIRE(config.get_filament_type(displayed, 0) == "PLA-S");
|
||||
REQUIRE(displayed == "Sup.PLA");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user