[Bf-blender-cvs] [e3ff9b2] master: Fix T46073: crash w/ out-of-bounds material

Campbell Barton noreply at git.blender.org
Tue Sep 15 23:55:39 CEST 2015


Commit: e3ff9b2044666ae04fc614a37e59e3dd01eeab4f
Author: Campbell Barton
Date:   Wed Sep 16 07:39:23 2015 +1000
Branches: master
https://developer.blender.org/rBe3ff9b2044666ae04fc614a37e59e3dd01eeab4f

Fix T46073: crash w/ out-of-bounds material

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

M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/makesdna/DNA_meshdata_types.h

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

diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index c3168c0..94758bc 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 064eace..5e333c2 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 b78cd65..e5cb222 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,




More information about the Bf-blender-cvs mailing list