diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-09-16 00:39:23 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-09-16 00:49:59 +0300 |
commit | e3ff9b2044666ae04fc614a37e59e3dd01eeab4f (patch) | |
tree | 6d4a45bce43fe58180f89cfc4877cfe33b589623 /source | |
parent | 7f63eaafd640a0b93492e0383265dd8f38d568bc (diff) |
Fix T46073: crash w/ out-of-bounds material
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 15 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 10 |
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, |