Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-09-16 00:39:23 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-09-16 00:49:59 +0300
commite3ff9b2044666ae04fc614a37e59e3dd01eeab4f (patch)
tree6d4a45bce43fe58180f89cfc4877cfe33b589623 /source
parent7f63eaafd640a0b93492e0383265dd8f38d568bc (diff)
Fix T46073: crash w/ out-of-bounds material
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c13
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c15
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h10
3 files changed, 26 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index c3168c0d6af..94758bc8566 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -867,6 +867,7 @@ static void cdDM_drawMappedFacesGLSL(
const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL);
const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
const int totpoly = dm->getNumPolys(dm);
+ const short totmat = dm->totmat;
int a, b, matnr, new_matnr;
bool do_draw;
int orig;
@@ -1047,8 +1048,9 @@ static void cdDM_drawMappedFacesGLSL(
}
for (a = 0; a < totpoly; a++, mpoly++) {
+ const short mat_nr = ME_MAT_NR_TEST(mpoly->mat_nr, totmat);
int j;
- int i = mat_orig_to_new[mpoly->mat_nr];
+ int i = mat_orig_to_new[mat_nr];
offset = tot_loops * max_element_size;
if (matconv[i].numdata != 0) {
@@ -1258,7 +1260,7 @@ static void cdDM_buffer_copy_triangles(
GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials;
int i, j, start;
- const int totmat = dm->drawObject->totmaterial;
+ const short totmat = dm->drawObject->totmaterial;
const MPoly *mpoly = dm->getPolyArray(dm);
const MLoopTri *lt = dm->getLoopTriArray(dm);
const int totpoly = dm->getNumPolys(dm);
@@ -1273,8 +1275,9 @@ static void cdDM_buffer_copy_triangles(
}
for (i = 0; i < totpoly; i++) {
+ const short mat_nr = ME_MAT_NR_TEST(mpoly[i].mat_nr, totmat);
int tottri = ME_POLY_TRI_TOT(&mpoly[i]);
- int mati = mat_orig_to_new[mpoly[i].mat_nr];
+ int mati = mat_orig_to_new[mat_nr];
gpumat = gpumaterials + mati;
if (mpoly[i].flag & ME_HIDE) {
@@ -1695,7 +1698,7 @@ static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
GPUDrawObject *gdo;
const MPoly *mpoly;
const MLoop *mloop;
- int totmat = dm->totmat;
+ const short totmat = dm->totmat;
GPUBufferMaterial *mat_info;
int i, totloops, totpolys;
@@ -1713,7 +1716,7 @@ static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
mat_info = MEM_callocN(sizeof(*mat_info) * totmat, "GPU_drawobject_new.mat_orig_to_new");
for (i = 0; i < totpolys; i++) {
- const int mat_nr = mpoly[i].mat_nr;
+ const short mat_nr = ME_MAT_NR_TEST(mpoly[i].mat_nr, totmat);
mat_info[mat_nr].totpolys++;
mat_info[mat_nr].totelements += 3 * ME_POLY_TRI_TOT(&mpoly[i]);
mat_info[mat_nr].totloops += mpoly[i].totloop;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 064eaced6e9..5e333c28fd9 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2007,7 +2007,7 @@ static void ccgDM_buffer_copy_triangles(
const int *mat_orig_to_new)
{
GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials;
- const int totmat = dm->drawObject->totmaterial;
+ const short totmat = dm->drawObject->totmaterial;
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
@@ -2015,7 +2015,8 @@ static void ccgDM_buffer_copy_triangles(
int gridFaces = gridSize - 1;
DMFlagMat *faceFlags = ccgdm->faceFlags;
int i, totface = ccgSubSurf_getNumFaces(ss);
- int matnr = -1, start;
+ short mat_nr = -1;
+ int start;
int totloops = 0;
FaceCount *fc = MEM_mallocN(sizeof(*fc) * totmat, "gpumaterial.facecount");
@@ -2036,14 +2037,14 @@ static void ccgDM_buffer_copy_triangles(
int mati;
if (faceFlags) {
- matnr = faceFlags[index].mat_nr;
+ mat_nr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, totmat);
is_hidden = (faceFlags[index].flag & ME_HIDE) != 0;
}
else {
- matnr = 0;
+ mat_nr = 0;
is_hidden = false;
}
- mati = mat_orig_to_new[matnr];
+ mati = mat_orig_to_new[mat_nr];
gpumat = dm->drawObject->materials + mati;
if (is_hidden) {
@@ -2539,7 +2540,7 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
GPUDrawObject *gdo;
DMFlagMat *faceFlags = ccgdm->faceFlags;
int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
- int totmat = (faceFlags) ? dm->totmat : 1;
+ const short totmat = (faceFlags) ? dm->totmat : 1;
GPUBufferMaterial *matinfo;
int i;
unsigned int tot_internal_edges = 0;
@@ -2559,7 +2560,7 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
CCGFace *f = ccgdm->faceMap[i].face;
int numVerts = ccgSubSurf_getFaceNumVerts(f);
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- int new_matnr = faceFlags[index].mat_nr;
+ const short new_matnr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, totmat);
matinfo[new_matnr].totelements += numVerts * gridFaces * gridFaces * 6;
matinfo[new_matnr].totloops += numVerts * gridFaces * gridFaces * 4;
matinfo[new_matnr].totpolys++;
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index b78cd65e913..e5cb222bdd8 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -446,6 +446,16 @@ enum {
/* number of tri's that make up this polygon once tessellated */
#define ME_POLY_TRI_TOT(mp) ((mp)->totloop - 2)
+/**
+ * Check out-of-bounds material, note that this is nearly always prevented,
+ * yet its still possible in rare cases.
+ * So usage such as array lookup needs to check.
+ */
+#define ME_MAT_NR_TEST(mat_nr, totmat) \
+ (CHECK_TYPE_ANY(mat_nr, short), \
+ CHECK_TYPE_ANY(totmat, short), \
+ (LIKELY(mat_nr < totmat) ? mat_nr : 0))
+
/* mselect->type */
enum {
ME_VSEL = 0,