From 1cdf8b19e5885c26f7341a0c21d243401a89d50e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 3 Apr 2022 10:49:20 +0200 Subject: Fix T96957: creating paint curve crashes This was essentially double free due to a dangling pointer, because `op->customdata` was not properly set to null after the paint stroke was freed. --- source/blender/editors/sculpt_paint/curves_sculpt_ops.cc | 2 +- source/blender/editors/sculpt_paint/paint_image_ops_paint.cc | 2 +- source/blender/editors/sculpt_paint/paint_intern.h | 2 +- source/blender/editors/sculpt_paint/paint_stroke.c | 6 +++++- source/blender/editors/sculpt_paint/paint_vertex.c | 4 ++-- source/blender/editors/sculpt_paint/sculpt.c | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index 382f0529daa..208db92abf7 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -710,7 +710,7 @@ static int sculpt_curves_stroke_modal(bContext *C, wmOperator *op, const wmEvent { SculptCurvesBrushStrokeData *op_data = static_cast( op->customdata); - int return_value = paint_stroke_modal(C, op, event, op_data->stroke); + int return_value = paint_stroke_modal(C, op, event, &op_data->stroke); if (ELEM(return_value, OPERATOR_FINISHED, OPERATOR_CANCELLED)) { MEM_delete(op_data); } diff --git a/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc index 786fcc47526..8ddf1614e41 100644 --- a/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc +++ b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc @@ -497,7 +497,7 @@ static int paint_exec(bContext *C, wmOperator *op) static int paint_modal(bContext *C, wmOperator *op, const wmEvent *event) { - return paint_stroke_modal(C, op, event, static_cast(op->customdata)); + return paint_stroke_modal(C, op, event, reinterpret_cast(&op->customdata)); } static void paint_cancel(bContext *C, wmOperator *op) diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 82fdf49c28e..bb0d05810a2 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -88,7 +88,7 @@ struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf); int paint_stroke_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event, - struct PaintStroke *stroke); + struct PaintStroke **stroke_p); int paint_stroke_exec(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke); void paint_stroke_cancel(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke); bool paint_stroke_flipped(struct PaintStroke *stroke); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 0f7b8ad1f3d..c5820ef3a2e 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -1389,10 +1389,11 @@ static void paint_stroke_line_constrain(PaintStroke *stroke, float mouse[2]) } } -int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke *stroke) +int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke **stroke_p) { Paint *p = BKE_paint_get_active_from_context(C); ePaintMode mode = BKE_paintmode_get_active_from_context(C); + PaintStroke *stroke = *stroke_p; Brush *br = stroke->brush = BKE_paint_brush(p); PaintSample sample_average; float mouse[2]; @@ -1441,6 +1442,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS /* one time initialization */ if (!stroke->stroke_init) { if (paint_stroke_curve_end(C, op, stroke)) { + *stroke_p = NULL; return OPERATOR_FINISHED; } @@ -1497,12 +1499,14 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS paint_stroke_line_constrain(stroke, mouse); paint_stroke_line_end(C, op, stroke, mouse); stroke_done(C, op, stroke); + *stroke_p = NULL; return OPERATOR_FINISHED; } } else if (ELEM(event->type, EVT_RETKEY, EVT_SPACEKEY)) { paint_stroke_line_end(C, op, stroke, sample_average.mouse); stroke_done(C, op, stroke); + *stroke_p = NULL; return OPERATOR_FINISHED; } else if (br->flag & BRUSH_LINE) { diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index c4d80d38100..3f0f97dffd2 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -2596,7 +2596,7 @@ static void wpaint_cancel(bContext *C, wmOperator *op) static int wpaint_modal(bContext *C, wmOperator *op, const wmEvent *event) { - return paint_stroke_modal(C, op, event, op->customdata); + return paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata); } void PAINT_OT_weight_paint(wmOperatorType *ot) @@ -3551,7 +3551,7 @@ static void vpaint_cancel(bContext *C, wmOperator *op) static int vpaint_modal(bContext *C, wmOperator *op, const wmEvent *event) { - return paint_stroke_modal(C, op, event, op->customdata); + return paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata); } void PAINT_OT_vertex_paint(wmOperatorType *ot) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3644c3177d3..e82ac058281 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5399,7 +5399,7 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) { - return paint_stroke_modal(C, op, event, op->customdata); + return paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata); } void SCULPT_OT_brush_stroke(wmOperatorType *ot) -- cgit v1.2.3