diff options
-rw-r--r-- | doc/contributions.txt | 2 | ||||
-rw-r--r-- | indra/llprimitive/llmodel.cpp | 114 | ||||
-rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 42 |
3 files changed, 133 insertions, 25 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index 33b2ded81d..8611331722 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -899,6 +899,8 @@ NickyD Nicky Dasmijn VWR-29228 MAINT-873 + STORM-1935 + STORM-1936 Nicky Perian OPEN-1 STORM-1087 diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 8f0120b064..4ef4744981 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -186,32 +186,78 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa LLVolumeFace::VertexMapData::PointMap point_map; - for (U32 i = 0; i < idx.getCount(); i += idx_stride) + U32 index_count = idx.getCount(); + U32 vertex_count = pos_source ? v.getCount() : 0; + U32 tc_count = tc_source ? tc.getCount() : 0; + U32 norm_count = norm_source ? n.getCount() : 0; + + for (U32 i = 0; i < index_count; i += idx_stride) { LLVolumeFace::VertexData cv; if (pos_source) { + // guard against model data specifiying out of range indices or verts + // + if (((i + pos_offset) > index_count) + || ((idx[i+pos_offset]*3+2) > vertex_count)) + { + return LLModel::BAD_ELEMENT; + } + cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0], v[idx[i+pos_offset]*3+1], v[idx[i+pos_offset]*3+2])); if (!cv.getPosition().isFinite3()) + { return LLModel::BAD_ELEMENT; + } } if (tc_source) { + // guard against model data specifiying out of range indices or tcs + // + if (((i + tc_offset) > index_count) + || ((idx[i+pos_offset]*2+1) > tc_count)) + { + return LLModel::BAD_ELEMENT; + } + cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0], tc[idx[i+tc_offset]*2+1]); + + if (!cv.mTexCoord.isFinite()) + { + llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } if (norm_source) { + // guard against model data specifiying out of range indices or norms + // + if (((i + pos_offset) > index_count) + || ((idx[i+pos_offset]*3+2) > vertex_count)) + { + return LLModel::BAD_ELEMENT; + } + if (((i + norm_offset) > index_count) + || ((idx[i+norm_offset]*3+2) > norm_count)) + { + return LLModel::BAD_ELEMENT; + } + cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0], n[idx[i+norm_offset]*3+1], n[idx[i+norm_offset]*3+2])); + if (!cv.getNormal().isFinite3()) + { + llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; return LLModel::BAD_ELEMENT; + } } BOOL found = FALSE; @@ -369,6 +415,11 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac LLVolumeFace::VertexMapData::PointMap point_map; + U32 index_count = idx.getCount(); + U32 vertex_count = pos_source ? v.getCount() : 0; + U32 tc_count = tc_source ? tc.getCount() : 0; + U32 norm_count = norm_source ? n.getCount() : 0; + U32 cur_idx = 0; for (U32 i = 0; i < vcount.getCount(); ++i) { //for each polygon @@ -381,22 +432,65 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac if (pos_source) { + // guard against model data specifiying out of range indices or verts + // + if (((i + pos_offset) > index_count) + || ((idx[i+pos_offset]*3+2) > vertex_count)) + { + return LLModel::BAD_ELEMENT; + } + cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0], v[idx[cur_idx+pos_offset]*3+1], v[idx[cur_idx+pos_offset]*3+2]); + + if (!cv.getPosition().isFinite3()) + { + llwarns << "Found NaN while loading positions from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } + } if (tc_source) { + // guard against model data specifiying out of range indices or tcs + // + if (((i + pos_offset) > index_count) + || ((idx[cur_idx+tc_offset]*2+1) > tc_count)) + { + return LLModel::BAD_ELEMENT; + } + cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0], tc[idx[cur_idx+tc_offset]*2+1]); + + if (!cv.mTexCoord.isFinite()) + { + llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } if (norm_source) { + // guard against model data specifiying out of range indices or norms + // + if (((i + pos_offset) > index_count) + || ((idx[cur_idx+norm_offset]*3+2) > norm_count)) + { + return LLModel::BAD_ELEMENT; + } + cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0], n[idx[cur_idx+norm_offset]*3+1], n[idx[cur_idx+norm_offset]*3+2]); + + if (!cv.getNormal().isFinite3()) + { + llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } cur_idx += idx_stride; @@ -637,6 +731,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac vert.getPosition().set(v->get(v_idx), v->get(v_idx+1), v->get(v_idx+2)); + + if (!vert.getPosition().isFinite3()) + { + llwarns << "Found NaN while loading position data from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } //bounds check n and t lookups because some FBX to DAE converters @@ -649,6 +749,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac vert.getNormal().set(n->get(n_idx), n->get(n_idx+1), n->get(n_idx+2)); + + if (!vert.getNormal().isFinite3()) + { + llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } else { @@ -662,6 +768,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount()); vert.mTexCoord.setVec(t->get(t_idx), t->get(t_idx+1)); + + if (!vert.mTexCoord.isFinite()) + { + llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl; + return LLModel::BAD_ELEMENT; + } } else { diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 8ea0b43b36..07c36b9f1b 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -290,6 +290,22 @@ bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a bool validate_face(const LLVolumeFace& face) { + + for (U32 v = 0; v < face.mNumVertices; v++) + { + if(face.mPositions && !face.mPositions[v].isFinite3()) + { + llwarns << "NaN position data in face found!" << llendl; + return false; + } + + if(face.mNormals && !face.mNormals[v].isFinite3()) + { + llwarns << "NaN normal data in face found!" << llendl; + return false; + } + } + for (U32 i = 0; i < face.mNumIndices; ++i) { if (face.mIndices[i] >= face.mNumVertices) @@ -305,30 +321,6 @@ bool validate_face(const LLVolumeFace& face) return false; } - for (U32 i = 0; i < face.mNumIndices; i+=3) - { - U16 idx1 = face.mIndices[i]; - U16 idx2 = face.mIndices[i+1]; - U16 idx3 = face.mIndices[i+2]; - - if (face.mPositions - && (!face.mPositions[idx1].isFinite3() - || !face.mPositions[idx2].isFinite3() - || !face.mPositions[idx3].isFinite3())) - { - llwarns << "NaN position data in face found!" << llendl; - return false; - } - - if (face.mNormals - && (!face.mNormals[idx1].isFinite3() - || !face.mNormals[idx2].isFinite3() - || !face.mNormals[idx3].isFinite3())) - { - llwarns << "NaN normal data in face found!" << llendl; - return false; - } - } /*const LLVector4a scale(0.5f); @@ -5959,3 +5951,5 @@ void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::stri LLNotificationsUtil::add("MeshUploadPermError"); } + + |