Commit: 1ffdb1b472f91425db0248170a8f3ba78f37fa09
Author: Campbell Barton
Date:   Fri Nov 6 19:37:50 2015 +1100
Branches: master
https://developer.blender.org/rB1ffdb1b472f91425db0248170a8f3ba78f37fa09

Fix T46696: Voxel crash indexing over INT_MAX

Use int64_t for index values.

===================================================================

M       source/blender/blenlib/BLI_voxel.h
M       source/blender/blenlib/intern/voxel.c
M       source/blender/render/intern/source/volume_precache.c

===================================================================

diff --git a/source/blender/blenlib/BLI_voxel.h 
b/source/blender/blenlib/BLI_voxel.h
index 7b92ac0..815d319 100644
--- a/source/blender/blenlib/BLI_voxel.h
+++ b/source/blender/blenlib/BLI_voxel.h
@@ -33,7 +33,11 @@
  */
 
 /** find the index number of a voxel, given x/y/z integer coords and 
resolution vector */
-#define BLI_VOXEL_INDEX(x, y, z, res) ((z) * (res)[1] * (res)[0] + (y) * 
(res)[0] + (x))
+
+#define BLI_VOXEL_INDEX(x, y, z, res) \
+       ((int64_t)(x) + \
+        (int64_t)(y) * (int64_t)(res)[0] + \
+        (int64_t)(z) * (int64_t)(res)[0] * (int64_t)(res)[1])
 
 /* all input coordinates must be in bounding box 0.0 - 1.0 */
 float BLI_voxel_sample_nearest(float *data, const int res[3], const float 
co[3]);
diff --git a/source/blender/blenlib/intern/voxel.c 
b/source/blender/blenlib/intern/voxel.c
index 5d58f9e..0933337 100644
--- a/source/blender/blenlib/intern/voxel.c
+++ b/source/blender/blenlib/intern/voxel.c
@@ -29,10 +29,10 @@
  *  \ingroup bli
  */
 
-
-#include "BLI_voxel.h"
 #include "BLI_utildefines.h"
+#include "BLI_voxel.h"
 
+#include "BLI_strict_flags.h"
 
 
 BLI_INLINE float D(float *data, const int res[3], int x, int y, int z)
@@ -49,9 +49,9 @@ float BLI_voxel_sample_nearest(float *data, const int res[3], 
const float co[3])
 {
        int xi, yi, zi;
        
-       xi = co[0] * res[0];
-       yi = co[1] * res[1];
-       zi = co[2] * res[2];
+       xi = (int)(co[0] * (float)res[0]);
+       yi = (int)(co[1] * (float)res[1]);
+       zi = (int)(co[2] * (float)res[2]);
        
        return D(data, res, xi, yi, zi);
 }
@@ -68,7 +68,7 @@ BLI_INLINE int FLOORI(float x)
  *
  * this causes the test (x + 2) < 0 with int x == 2147483647 to return false 
(x being an integer,
  * x + 2 should wrap around to -2147483647 so the test < 0 should return true, 
which it doesn't) */
-BLI_INLINE int _clamp(int a, int b, int c)
+BLI_INLINE int64_t _clamp(int a, int b, int c)
 {
        return (a < b) ? b : ((a > c) ? c : a);
 }
@@ -77,15 +77,24 @@ float BLI_voxel_sample_trilinear(float *data, const int 
res[3], const float co[3
 {
        if (data) {
        
-               const float xf = co[0] * res[0] - 0.5f;
-               const float yf = co[1] * res[1] - 0.5f;
-               const float zf = co[2] * res[2] - 0.5f;
+               const float xf = co[0] * (float)res[0] - 0.5f;
+               const float yf = co[1] * (float)res[1] - 0.5f;
+               const float zf = co[2] * (float)res[2] - 0.5f;
                
                const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
        
-               const int xc[2] = {_clamp(x, 0, res[0] - 1), _clamp(x + 1, 0, 
res[0] - 1)};
-               const int yc[2] = {res[0] * _clamp(y, 0, res[1] - 1), res[0] * 
_clamp(y + 1, 0, res[1] - 1)};
-               const int zc[2] = {res[0] * res[1] * _clamp(z, 0, res[2] - 1), 
res[0] * res[1] * _clamp(z + 1, 0, res[2] - 1)};
+               const int64_t xc[2] = {
+                   _clamp(x,     0, res[0] - 1),
+                   _clamp(x + 1, 0, res[0] - 1),
+               };
+               const int64_t yc[2] = {
+                   _clamp(y,     0, res[1] - 1) * res[0],
+                   _clamp(y + 1, 0, res[1] - 1) * res[0],
+               };
+               const int64_t zc[2] = {
+                   _clamp(z,     0, res[2] - 1) * res[0] * res[1],
+                   _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
+               };
        
                const float dx = xf - (float)x;
                const float dy = yf - (float)y;
@@ -103,18 +112,31 @@ float BLI_voxel_sample_trilinear(float *data, const int 
res[3], const float co[3
        }
        return 0.f;
 }
-       
 
 float BLI_voxel_sample_triquadratic(float *data, const int res[3], const float 
co[3])
 {
        if (data) {
 
-               const float xf = co[0] * res[0], yf = co[1] * res[1], zf = 
co[2] * res[2];
+               const float xf = co[0] * (float)res[0];
+               const float yf = co[1] * (float)res[1];
+               const float zf = co[2] * (float)res[2];
                const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
 
-               const int xc[3] = {_clamp(x - 1, 0, res[0] - 1), _clamp(x, 0, 
res[0] - 1), _clamp(x + 1, 0, res[0] - 1)};
-               const int yc[3] = {res[0] * _clamp(y - 1, 0, res[1] - 1), 
res[0] * _clamp(y, 0, res[1] - 1), res[0] * _clamp(y + 1, 0, res[1] - 1)};
-               const int zc[3] = {res[0] * res[1] * _clamp(z - 1, 0, res[2] - 
1), res[0] * res[1] * _clamp(z, 0, res[2] - 1), res[0] * res[1] * _clamp(z + 1, 
0, res[2] - 1)};
+               const int64_t xc[3] = {
+                   _clamp(x - 1, 0, res[0] - 1),
+                   _clamp(x,     0, res[0] - 1),
+                   _clamp(x + 1, 0, res[0] - 1),
+               };
+               const int64_t yc[3] = {
+                   _clamp(y - 1, 0, res[1] - 1) * res[0],
+                   _clamp(y,     0, res[1] - 1) * res[0],
+                   _clamp(y + 1, 0, res[1] - 1) * res[0],
+               };
+               const int64_t zc[3] = {
+                   _clamp(z - 1, 0, res[2] - 1) * res[0] * res[1],
+                   _clamp(z,     0, res[2] - 1) * res[0] * res[1],
+                   _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
+               };
 
                const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - 
(float)z;
                const float u[3] = {dx * (0.5f * dx - 1.f) + 0.5f, dx * (1.0f - 
dx) + 0.5f, 0.5f * dx * dx};
@@ -139,13 +161,29 @@ float BLI_voxel_sample_tricubic(float *data, const int 
res[3], const float co[3]
 {
        if (data) {
 
-               const float xf = co[0] * res[0] - 0.5f, yf = co[1] * res[1] - 
0.5f, zf = co[2] * res[2] - 0.5f;
+               const float xf = co[0] * (float)res[0] - 0.5f;
+               const float yf = co[1] * (float)res[1] - 0.5f;
+               const float zf = co[2] * (float)res[2] - 0.5f;
                const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
 
-               const int xc[4] = {_clamp(x - 1, 0, res[0] - 1), _clamp(x, 0, 
res[0] - 1), _clamp(x + 1, 0, res[0] - 1), _clamp(x + 2, 0, res[0] - 1)};
-               const int yc[4] = {res[0] * _clamp(y - 1, 0, res[1] - 1), 
res[0] * _clamp(y, 0, res[1] - 1), res[0] * _clamp(y + 1, 0, res[1] - 1), 
res[0] * _clamp(y + 2, 0, res[1] - 1)};
-               const int zc[4] = {res[0] * res[1] * _clamp(z - 1, 0, res[2] - 
1), res[0] * res[1] * _clamp(z, 0, res[2] - 1), res[0] * res[1] * _clamp(z + 1, 
0, res[2] - 1), res[0] * res[1] * _clamp(z + 2, 0, res[2] - 1)};
-
+               const int64_t xc[4] = {
+                   _clamp(x - 1, 0, res[0] - 1),
+                   _clamp(x,     0, res[0] - 1),
+                   _clamp(x + 1, 0, res[0] - 1),
+                   _clamp(x + 2, 0, res[0] - 1),
+               };
+               const int64_t yc[4] = {
+                   _clamp(y - 1, 0, res[1] - 1) * res[0],
+                   _clamp(y,     0, res[1] - 1) * res[0],
+                   _clamp(y + 1, 0, res[1] - 1) * res[0],
+                   _clamp(y + 2, 0, res[1] - 1) * res[0],
+               };
+               const int64_t zc[4] = {
+                   _clamp(z - 1, 0, res[2] - 1) * res[0] * res[1],
+                   _clamp(z,     0, res[2] - 1) * res[0] * res[1],
+                   _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
+                   _clamp(z + 2, 0, res[2] - 1) * res[0] * res[1],
+               };
                const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - 
(float)z;
 
                float u[4], v[4], w[4];
diff --git a/source/blender/render/intern/source/volume_precache.c 
b/source/blender/render/intern/source/volume_precache.c
index 78ede01..6f09e9c 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -181,7 +181,7 @@ static float get_avg_surrounds(float *cache, int *res, int 
xx, int yy, int zz)
                                        for (x=-1; x <= 1; x++) {
                                                x_ = xx+x;
                                                if (x_ >= 0 && x_ <= res[0]-1) {
-                                                       const int i = 
BLI_VOXEL_INDEX(x_, y_, z_, res);
+                                                       const int64_t i = 
BLI_VOXEL_INDEX(x_, y_, z_, res);
                                                        
                                                        if (cache[i] > 0.0f) {
                                                                tot += cache[i];
@@ -212,7 +212,7 @@ static void lightcache_filter(VolumePrecache *vp)
                for (y=0; y < vp->res[1]; y++) {
                        for (x=0; x < vp->res[0]; x++) {
                                /* trigger for outside mesh */
-                               const int i = BLI_VOXEL_INDEX(x, y, z, vp->res);
+                               const int64_t i = BLI_VOXEL_INDEX(x, y, z, 
vp->res);
                                
                                if (vp->data_r[i] < -0.f)
                                        vp->data_r[i] = 
get_avg_surrounds(vp->data_r, vp->res, x, y, z);
@@ -244,7 +244,7 @@ static void lightcache_filter2(VolumePrecache *vp)
                for (y=0; y < vp->res[1]; y++) {
                        for (x=0; x < vp->res[0]; x++) {
                                /* trigger for outside mesh */
-                               const int i = BLI_VOXEL_INDEX(x, y, z, vp->res);
+                               const int64_t i = BLI_VOXEL_INDEX(x, y, z, 
vp->res);
                                if (vp->data_r[i] < -0.f)
                                        new_r[i] = 
get_avg_surrounds(vp->data_r, vp->res, x, y, z);
                                if (vp->data_g[i] < -0.f)
@@ -265,22 +265,30 @@ static void lightcache_filter2(VolumePrecache *vp)
 }
 #endif
 
-BLI_INLINE int ms_I(int x, int y, int z, int *n) /* has a pad of 1 voxel 
surrounding the core for boundary simulation */
+/* has a pad of 1 voxel surrounding the core for boundary simulation */
+BLI_INLINE int64_t ms_I(int x, int y, int z, const int *n)
 {
        /* different ordering to light cache */
-       return x*(n[1]+2)*(n[2]+2) + y*(n[2]+2) + z;
+       return ((int64_t)x * (int64_t)(n[1] + 2) * (int64_t)(n[2] + 2) +
+               (int64_t)y * (int64_t)(n[2] + 2) +
+               (int64_t)z);
 }
 
-BLI_INLINE int v_I_pad(int x, int y, int z, int *n) /* has a pad of 1 voxel 
surrounding the core for boundary simulation */
+/* has a pad of 1 voxel surrounding the core for boundary simulation */
+BLI_INLINE int64_t v_I_pad(int x, int y, int z, const int *n)
 {
        /* same ordering to light cache, with padding */
-       return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
+       return ((int64_t)z * (int64_t)(n[1] + 2) * (int64_t)(n[0] + 2) +
+               (int64_t)y * (int64_t)(n[0] + 2) +
+               (int64_t)x);
 }
 
-BLI_INLINE int lc_to_ms_I(int x, int y, int z, int *n)
+BLI_INLINE int64_t lc_to_ms_I(int x, int y, int z, const int *n)
 { 
        /* converting light cache index to multiple scattering index */
-       return (x-1)*(n[1]*n[2]) + (y-1)*(n[2]) + z-1;
+       return ((int64_t)(x - 1) * ((int64_t)n[1] * (int64_t)n[2]) +
+               (int64_t)(y - 1) * ((int64_t)n[2]) +
+               (int64_t)(z - 1));
 }
 
 /* *** multiple scattering approximation *** */
@@ -295,7 +303,7 @@ static float total_ss_energy(Render *re, int do_test_break, 
VolumePrecache *vp)
        for (z=0; z < res[2]; z++) {
                for (y=0; y < res[1]; y++) {
                        for (x=0; x < res[0]; x++) {
-                               const int i = BLI_VOXEL_INDEX(x, y, z, res);
+                               const int64_t i = BLI_VOXEL_INDEX(x, y, z, res);
                        
                                if (vp->data_r[i] > 0.f) energy += 
vp->data_r[i];
                                if (vp->data_g[i] > 0.f) energy += 
vp->data_g[i];
@@ -309,7 +317,7 @@ static float total_ss_energy(Render *re, int do_test_break, 
VolumePrecache *vp)
        return energy;
 }
 
-static float total_ms_energy(Render *re, int do_test_break, float *sr, float 
*sg, float *sb, int *res)
+static float total_ms_energy(Render *re, int do_test_break, float *sr, float 
*sg, float *sb, const int res[3])
 {
        int x, y, z;
        float energy=0.f;
@@ -317,7 +325,7 @@ static float total_ms_energy(Render *re, in

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to