summaryrefslogtreecommitdiff
path: root/indra/llprimitive/llmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llprimitive/llmodel.cpp')
-rw-r--r--indra/llprimitive/llmodel.cpp140
1 files changed, 126 insertions, 14 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 5ed05e2201..ef6eb75a6b 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -186,27 +186,73 @@ 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 + 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;
@@ -261,13 +307,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
@@ -292,13 +338,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
}
@@ -364,6 +410,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
@@ -376,22 +427,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;
@@ -480,13 +574,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
@@ -514,13 +608,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
}
@@ -632,6 +726,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
@@ -644,6 +744,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
{
@@ -657,6 +763,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
{
@@ -730,13 +842,13 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
LLVolumeFace& new_face = *face_list.rbegin();
if (!n)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!t)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
}
@@ -1036,7 +1148,7 @@ void LLModel::setVolumeFaceData(
}
else
{
- ll_aligned_free_16(face.mNormals);
+ //ll_aligned_free_16(face.mNormals);
face.mNormals = NULL;
}
@@ -1047,7 +1159,7 @@ void LLModel::setVolumeFaceData(
}
else
{
- ll_aligned_free_16(face.mTexCoords);
+ //ll_aligned_free_16(face.mTexCoords);
face.mTexCoords = NULL;
}
@@ -1246,7 +1358,7 @@ void LLModel::generateNormals(F32 angle_cutoff)
}
else
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}