mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-14 22:41:05 +00:00
test(libnest2d): fix use-after-free crash in NfpPlacer lifetime tests
NfpPlacer stores std::reference_wrapper to the items it packs and re-reads them from finalAlign() in its destructor (via clearItems()). Two placer tests declared the placer before the items in the same scope, so the items were destroyed first and the destructor dereferenced dangling references. On macOS this is a deterministic SIGSEGV: libmalloc poisons the freed block on free, so the item's point vector reads back as ~null (deref at 0x8). On Linux/glibc the freed bytes usually survive, which is why it slipped through upstream CI (introduced by #14267). Declare the items before the placer so they outlive it, matching the pattern the sibling 'packs many items' and 'obstacle' tests already use. Test-only; the library lifetime contract (items must outlive the placer) is unchanged and honored in production via _Nester in Arrange.cpp.
This commit is contained in:
@@ -56,8 +56,10 @@ struct NfpPlacerFixture {
|
||||
} // namespace
|
||||
|
||||
TEST_CASE_METHOD(NfpPlacerFixture, "NfpPlacer places a single item inside the bin", "[Nesting][Placer]") {
|
||||
NfpPlacer placer = placer_with();
|
||||
// The placer only keeps references to the items it packs and re-reads them
|
||||
// from finalAlign() in its destructor, so the item must outlive the placer.
|
||||
RectangleItem item{100000000, 100000000};
|
||||
NfpPlacer placer = placer_with();
|
||||
|
||||
REQUIRE(place(placer, item));
|
||||
REQUIRE(placer.getItems().size() == 1u);
|
||||
@@ -103,12 +105,15 @@ TEST_CASE_METHOD(NfpPlacerFixture, "NfpPlacer packs many items without overlap",
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(NfpPlacerFixture, "NfpPlacer evaluates the rotation candidates", "[Nesting][Placer]") {
|
||||
// The placer re-reads its packed items from finalAlign() in its destructor,
|
||||
// so the items must outlive the placer — declare them first.
|
||||
std::vector<RectangleItem> rects = {
|
||||
{180000000, 40000000}, {180000000, 40000000}, {180000000, 40000000}};
|
||||
|
||||
Cfg cfg;
|
||||
cfg.rotations = {0.0, Pi / 2.0}; // exercise the rotation search loop
|
||||
NfpPlacer placer = placer_with(cfg);
|
||||
|
||||
std::vector<RectangleItem> rects = {
|
||||
{180000000, 40000000}, {180000000, 40000000}, {180000000, 40000000}};
|
||||
place_all(placer, rects);
|
||||
require_disjoint_in_bin(rects);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user