Fix T71260: GPencil crash when drawing very long lines
authorAntonio Vazquez <blendergit@gmail.com>
Sat, 2 Nov 2019 09:28:08 +0000 (10:28 +0100)
committerAntonio Vazquez <blendergit@gmail.com>
Sat, 2 Nov 2019 09:28:37 +0000 (10:28 +0100)
There were two problems:

1) When the buffer was reallocate, the pointer was corrupted.
2) Short variables were too small to hold long lines.

source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/gpencil/gpencil_utils.c
source/blender/editors/include/ED_gpencil.h
source/blender/makesdna/DNA_gpencil_types.h

index f29e782c61842caa919276a5a30543a89e4b8f85..bebdcb34326ce9e3c8ef430286b41c6d92b06fc9 100644 (file)
@@ -3660,7 +3660,6 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
   tGPsdata *p = op->customdata;
   ToolSettings *ts = CTX_data_tool_settings(C);
   GP_Sculpt_Guide *guide = &p->scene->toolsettings->gp_sculpt.guide;
-  tGPspoint *points = (tGPspoint *)p->gpd->runtime.sbuffer;
 
   /* default exit state - pass through to support MMB view nav, etc. */
   int estate = OPERATOR_PASS_THROUGH;
@@ -3969,6 +3968,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
       int size_after = p->gpd->runtime.sbuffer_used;
 
       /* Last point of the event is always real (not fake). */
+      tGPspoint *points = (tGPspoint *)p->gpd->runtime.sbuffer;
       tGPspoint *pt = &points[size_after - 1];
       pt->tflag &= ~GP_TPOINT_FAKE;
 
index b194d28a8b8120eea9f17dec416af34871cb9127..3ca993673d4efeecc2618cd4eba78e208b2cfa72 100644 (file)
@@ -2530,8 +2530,8 @@ void ED_gpencil_select_toggle_all(bContext *C, int action)
 
 /* Ensure the SBuffer (while drawing stroke) size is enough to save all points of the stroke */
 tGPspoint *ED_gpencil_sbuffer_ensure(tGPspoint *buffer_array,
-                                     short *buffer_size,
-                                     short *buffer_used,
+                                     int *buffer_size,
+                                     int *buffer_used,
                                      const bool clear)
 {
   tGPspoint *p = NULL;
index 0ff1b8bb40b524c4f77978498ed84c3383ccbc99..dce0e3931be9e81ed2788b04aba833aaf5454729 100644 (file)
@@ -292,8 +292,8 @@ void ED_gpencil_select_toggle_all(struct bContext *C, int action);
 
 /* Ensure stroke sbuffer size is enough */
 struct tGPspoint *ED_gpencil_sbuffer_ensure(struct tGPspoint *buffer_array,
-                                            short *buffer_size,
-                                            short *buffer_used,
+                                            int *buffer_size,
+                                            int *buffer_used,
                                             const bool clear);
 /* Tag all scene grease pencil object to update. */
 void ED_gpencil_tag_scene_gpencil(struct Scene *scene);
index 1435d0a64b4f4e6946ef40a46ac672e10ec2f22f..33dfe66a151d920451005ce74e29ce3f2d03a24d 100644 (file)
@@ -447,17 +447,16 @@ typedef struct bGPdata_Runtime {
    * - buffer must be initialized before use, but freed after
    *   whole paint operation is over
    */
-  /** Number of elements currently used in cache. */
-  short sbuffer_used;
   /** Flags for stroke that cache represents. */
   short sbuffer_sflag;
+  /** Number of elements currently used in cache. */
+  int sbuffer_used;
   /** Number of total elements available in cache. */
-  short sbuffer_size;
-  char _pad[4];
+  int sbuffer_size;
 
   /** Number of control-points for stroke. */
   int tot_cp_points;
-  char _pad1_[4];
+  char _pad_[4];
   /** Array of control-points for stroke. */
   bGPDcontrolpoint *cp_points;
 } bGPdata_Runtime;