Fix panel type use after free when reloading scripts

In order to prevent the panel code from using the type after it is freed,
the field needs to be set to NULL. This needs to be done recursively
for subpanels as well as top-level panels.
This commit is contained in:
Hans Goudey 2020-10-21 08:25:46 -05:00
parent d782bad62d
commit 35e50c170c
1 changed files with 12 additions and 3 deletions

View File

@ -180,6 +180,17 @@ static void panel_draw_header_preset(const bContext *C, Panel *panel)
RNA_parameter_list_free(&list);
}
static void remove_panel_type_recursive(Panel *panel, const PanelType *pt)
{
if (panel->type == pt) {
panel->type = NULL;
}
LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
remove_panel_type_recursive(child_panel, pt);
}
}
static void rna_Panel_unregister(Main *bmain, StructRNA *type)
{
ARegionType *art;
@ -220,9 +231,7 @@ static void rna_Panel_unregister(Main *bmain, StructRNA *type)
LISTBASE_FOREACH (ARegion *, region, regionbase) {
if (region->type == art) {
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
if (panel->type == pt) {
panel->type = NULL;
}
remove_panel_type_recursive(panel, pt);
}
}
/* The unregistered panel might have had a template that added instanced panels,