Fix #111713: Nodes crash when library overriding

Library overrides crashed with on trying to access the interface root
panel. The root panel should not be exposed through RNA, but also
accessing its position property should be allowed.

Several fixes here:
- Fix position property getter when the item has no parent panel
  (i.e. the root panel).
- Avoid infinite loops in the greedy override comparison: exclude the
  loopback parent property.
- Don't return the root panel via the parent property in the first
  place, just return nullptr.

Second attempt at fix, first one in #111755 broke the
bl_node_group_interface test due to incorrect handling of the nullptr
parent case (reverted by 68440742)

Pull Request: https://projects.blender.org/blender/blender/pulls/111782
This commit is contained in:
Lukas Tönne
2023-09-01 12:39:51 +02:00
parent d361d67e11
commit cf12d11de6
3 changed files with 16 additions and 7 deletions

View File

@@ -1205,7 +1205,7 @@ bNodeTreeInterfaceItem *bNodeTreeInterface::insert_item_copy(const bNodeTreeInte
bool bNodeTreeInterface::remove_item(bNodeTreeInterfaceItem &item, bool move_content_to_parent)
{
bNodeTreeInterfacePanel *parent = this->find_item_parent(item);
bNodeTreeInterfacePanel *parent = this->find_item_parent(item, true);
if (parent == nullptr) {
return false;
}

View File

@@ -246,7 +246,10 @@ typedef struct bNodeTreeInterface {
/* const_cast to avoid a const version of #find_parent_recursive. */
const bNodeTreeInterfacePanel *parent =
const_cast<bNodeTreeInterfacePanel &>(root_panel).find_parent_recursive(item);
BLI_assert(parent != nullptr);
if (parent == nullptr || parent == &root_panel) {
/* Panel is the root panel. */
return 0;
}
return parent->item_position(item);
}
/**
@@ -274,11 +277,19 @@ typedef struct bNodeTreeInterface {
}
/**
* Find the panel containing the item.
* \param include_root: Allow #root_panel as a return value,
* otherwise return nullptr for root items.
* \return Parent panel containing the item.
*/
bNodeTreeInterfacePanel *find_item_parent(const bNodeTreeInterfaceItem &item)
bNodeTreeInterfacePanel *find_item_parent(const bNodeTreeInterfaceItem &item,
bool include_root = false)
{
return root_panel.find_parent_recursive(item);
bNodeTreeInterfacePanel *parent = root_panel.find_parent_recursive(item);
/* Return nullptr instead the root panel. */
if (!include_root && parent == &root_panel) {
return nullptr;
}
return parent;
}
/**

View File

@@ -554,9 +554,6 @@ static bNodeTreeInterfaceItem *rna_NodeTreeInterfaceItems_copy(ID *id,
{
/* Copy to same parent as the item. */
bNodeTreeInterfacePanel *parent = interface->find_item_parent(*item);
if (parent == nullptr) {
return nullptr;
}
return rna_NodeTreeInterfaceItems_copy_to_parent(id, interface, bmain, reports, item, parent);
}
@@ -850,6 +847,7 @@ static void rna_def_node_interface_item(BlenderRNA *brna)
RNA_def_property_pointer_funcs(
prop, "rna_NodeTreeInterfaceItem_parent_get", nullptr, nullptr, nullptr);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Parent", "Panel that contains the item");
prop = RNA_def_property(srna, "position", PROP_INT, PROP_NONE);