Fix: Node operators crash when 'region' is null #104994

Open
Erik Abrahamsson wants to merge 1 commits from erik85/blender:node-context-crashes into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
7 changed files with 157 additions and 7 deletions

View File

@ -11692,6 +11692,9 @@ void UI_screen_free_active_but_highlight(const bContext *C, bScreen *screen)
uiBut *UI_but_active_drop_name_button(const bContext *C)
{
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
return nullptr;
}
uiBut *but = ui_region_find_active_but(region);
if (but) {

View File

@ -136,6 +136,12 @@ struct RerouteCutsForSocket {
static int add_reroute_exec(bContext *C, wmOperator *op)
{
const ARegion &region = *CTX_wm_region(C);
if (&region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &ntree = *snode.edittree;
const Span<float2> socket_locations = snode.runtime->all_socket_locations;
@ -341,6 +347,11 @@ static int node_add_group_invoke(bContext *C, wmOperator *op, const wmEvent *eve
ARegion *region = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
/* Convert mouse coordinates to v2d space. */
UI_view2d_region_to_view(&region->v2d,
event->mval[0],
@ -423,6 +434,11 @@ static int node_add_group_asset_invoke(bContext *C, wmOperator *op, const wmEven
ARegion &region = *CTX_wm_region(C);
SpaceNode &snode = *CTX_wm_space_node(C);
if (&region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
const AssetLibraryReference *library_ref = CTX_wm_asset_library_ref(C);
if (!library_ref) {
return OPERATOR_CANCELLED;
@ -517,6 +533,11 @@ static int node_add_object_invoke(bContext *C, wmOperator *op, const wmEvent *ev
ARegion *region = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
/* Convert mouse coordinates to v2d space. */
UI_view2d_region_to_view(&region->v2d,
event->mval[0],
@ -719,6 +740,11 @@ static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *even
ARegion *region = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
/* Convert mouse coordinates to `v2d` space. */
UI_view2d_region_to_view(&region->v2d,
event->mval[0],
@ -924,6 +950,11 @@ static int node_add_search_invoke(bContext *C, wmOperator *op, const wmEvent *ev
{
const ARegion &region = *CTX_wm_region(C);
if (&region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
float2 cursor;
UI_view2d_region_to_view(&region.v2d, event->mval[0], event->mval[1], &cursor.x, &cursor.y);

View File

@ -907,6 +907,12 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
bNode *node = nodeGetActive(snode->edittree);
NodeSizeWidget *nsw = (NodeSizeWidget *)op->customdata;
@ -1011,6 +1017,12 @@ static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
const bNode *node = nodeGetActive(snode->edittree);
if (node == nullptr) {

View File

@ -21,6 +21,7 @@
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "BKE_screen.h"
#include "ED_node.hh" /* own include */
@ -1329,6 +1330,11 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
SpaceNode &snode = *CTX_wm_space_node(C);
ARegion &region = *CTX_wm_region(C);
if (&region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
bool detach = RNA_boolean_get(op->ptr, "detach");
int2 mval;
@ -1454,6 +1460,11 @@ static int cut_links_exec(bContext *C, wmOperator *op)
SpaceNode &snode = *CTX_wm_space_node(C);
const ARegion &region = *CTX_wm_region(C);
if (&region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
Vector<float2> path;
RNA_BEGIN (op->ptr, itemptr, "path") {
float2 loc_region;
@ -1562,6 +1573,12 @@ static int mute_links_exec(bContext *C, wmOperator *op)
Main &bmain = *CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
const ARegion &region = *CTX_wm_region(C);
if (&region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
bNodeTree &ntree = *snode.edittree;
const Span<float2> socket_locations = snode.runtime->all_socket_locations;
@ -1866,9 +1883,15 @@ static bNode *node_find_frame_to_attach(ARegion &region,
return nullptr;
}
static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
static int node_attach_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion &region = *CTX_wm_region(C);
if (&region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &ntree = *snode.edittree;
bNode *frame = node_find_frame_to_attach(region, ntree, event->mval);
@ -2562,13 +2585,20 @@ static int node_insert_offset_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
BLI_assert((snode->flag & SNODE_SKIP_INSOFFSET) == 0);
iofsd->ntree = snode->edittree;
iofsd->anim_timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.02);
node_link_insert_offset_ntree(
iofsd, CTX_wm_region(C), event->mval, (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT));
iofsd, region, event->mval, (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT));
/* add temp handler */
WM_event_add_modal_handler(C, op);

View File

@ -24,6 +24,7 @@
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "BKE_workspace.h"
#include "ED_node.h" /* own include */
@ -1239,6 +1240,12 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
const bool prev = RNA_boolean_get(op->ptr, "prev");
bNode &active_node = *nodeGetActive(snode->edittree);

View File

@ -17,6 +17,7 @@
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "BKE_report.h"
#include "BKE_screen.h"
#include "ED_image.h"
@ -110,6 +111,12 @@ bool space_node_view_flag(
static int node_view_all_exec(bContext *C, wmOperator *op)
{
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
SpaceNode *snode = CTX_wm_space_node(C);
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
@ -147,6 +154,12 @@ void NODE_OT_view_all(wmOperatorType *ot)
static int node_view_selected_exec(bContext *C, wmOperator *op)
{
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
SpaceNode *snode = CTX_wm_space_node(C);
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
@ -238,6 +251,12 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
NodeViewMove *nvm;
Image *ima;
ImBuf *ibuf;
@ -307,6 +326,12 @@ static int backimage_zoom_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
float fac = RNA_float_get(op->ptr, "factor");
snode->zoom *= fac;
@ -342,12 +367,17 @@ void NODE_OT_backimage_zoom(wmOperatorType *ot)
/** \name Background Image Fit
* \{ */
static int backimage_fit_exec(bContext *C, wmOperator * /*op*/)
static int backimage_fit_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
Image *ima;
ImBuf *ibuf;
@ -644,6 +674,11 @@ static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ARegion *region = CTX_wm_region(C);
ImageSampleInfo *info;
if (region == nullptr) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
/* Don't handle events intended for nodes (which rely on click/drag distinction).
* which this operator would use since sampling is normally activated on press, see: #98191. */
if (node_or_socket_isect_event(*C, *event)) {

View File

@ -19,6 +19,7 @@
#include "BLI_rect.h"
#include "BKE_context.h"
#include "BKE_report.h"
#include "WM_api.h"
#include "WM_types.h"
@ -164,6 +165,12 @@ int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
const ARegion *region = CTX_wm_region(C);
if (region == NULL) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
const bool wait_for_input = !WM_event_is_mouse_drag_or_press(event) &&
RNA_boolean_get(op->ptr, "wait_for_input");
@ -286,10 +293,17 @@ static void gesture_circle_apply(bContext *C, wmOperator *op);
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
const ARegion *region = CTX_wm_region(C);
if (region == NULL) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
const bool wait_for_input = !WM_event_is_mouse_drag_or_press(event) &&
RNA_boolean_get(op->ptr, "wait_for_input");
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_CIRCLE);
op->customdata = WM_gesture_new(win, region, event, WM_GESTURE_CIRCLE);
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@ -477,9 +491,15 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
PropertyRNA *prop;
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_LASSO);
if (region == NULL) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
op->customdata = WM_gesture_new(win, region, event, WM_GESTURE_LASSO);
/* add modal handler */
WM_event_add_modal_handler(C, op);
@ -496,9 +516,15 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
PropertyRNA *prop;
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_LINES);
if (region == NULL) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
op->customdata = WM_gesture_new(win, region, event, WM_GESTURE_LINES);
/* add modal handler */
WM_event_add_modal_handler(C, op);
@ -736,9 +762,15 @@ static bool gesture_straightline_apply(bContext *C, wmOperator *op)
int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
PropertyRNA *prop;
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_STRAIGHTLINE);
if (region == NULL) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "Missing 'region' in context");
return OPERATOR_CANCELLED;
}
op->customdata = WM_gesture_new(win, region, event, WM_GESTURE_STRAIGHTLINE);
if (WM_event_is_mouse_drag_or_press(event)) {
wmGesture *gesture = op->customdata;