Fix crash in some cases when deleting particle systems.
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 15 Sep 2016 09:50:56 +0000 (11:50 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 15 Sep 2016 09:50:56 +0000 (11:50 +0200)
Those 'never null' ID pointers are really a PITA to handle... luckily we don't have much of those around!

Found by Sybren, thanks.

Should be backported to 2.78.

source/blender/blenkernel/BKE_library_remap.h
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c

index e974b79ee66781692c5975c993b751695070d6c0..89b087014b2a573fdbb927bd34c2261d3841ccb6 100644 (file)
@@ -44,7 +44,7 @@ enum {
         * (like e.g. Object->data). */
        ID_REMAP_FLAG_NEVER_NULL_USAGE  = 1 << 2,
        /* This tells the callback func to force setting IDs using target one with a 'never NULL' pointer to NULL.
-        * WARNING! Use with extreme care, this will leave database in broken state! */
+        * WARNING! Use with extreme care, this will leave database in broken state and can cause crashes very easily! */
        ID_REMAP_FORCE_NEVER_NULL_USAGE = 1 << 3,
 };
 
index 907721b09b67701265fae3d8a3b72d3f4048921e..1ea275585458e11cf8d856d177a069e908ff0605 100644 (file)
@@ -503,7 +503,9 @@ void psys_free_particles(ParticleSystem *psys)
        PARTICLE_P;
 
        if (psys->particles) {
-               if (psys->part->type == PART_HAIR) {
+               /* Even though psys->part should never be NULL, this can happen as an exception during deletion.
+                * See ID_REMAP_SKIP/FORCE/FLAG_NEVER_NULL_USAGE in BKE_library_remap. */
+               if (psys->part && psys->part->type == PART_HAIR) {
                        LOOP_PARTICLES {
                                if (pa->hair)
                                        MEM_freeN(pa->hair);
index b4e951ce04ace1001364ed29d8e6bceb11ad3def..efaf1f9df2b7fa54074677d487ce11cd934918f5 100644 (file)
@@ -4336,7 +4336,9 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
                func(psys, (ID **)&pt->ob, userdata, IDWALK_NOP);
        }
 
-       if (psys->part->phystype == PART_PHYS_BOIDS) {
+       /* Even though psys->part should never be NULL, this can happen as an exception during deletion.
+        * See ID_REMAP_SKIP/FORCE/FLAG_NEVER_NULL_USAGE in BKE_library_remap. */
+       if (psys->part && psys->part->phystype == PART_PHYS_BOIDS) {
                ParticleData *pa;
                int p;