summaryrefslogtreecommitdiff
path: root/indra/llprimitive
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llprimitive')
-rw-r--r--indra/llprimitive/llmodel.cpp114
1 files changed, 113 insertions, 1 deletions
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
{