Adds safety and prevents crashes for damaged files

pull/486/head
DenisMikhalev 2015-03-09 19:40:13 +03:00
parent 727888ea10
commit 62676b56aa
1 changed files with 45 additions and 27 deletions

View File

@ -64,6 +64,24 @@ static const aiImporterDesc desc = {
"ply" "ply"
}; };
// ------------------------------------------------------------------------------------------------
// Internal stuff
namespace
{
// ------------------------------------------------------------------------------------------------
// Checks that property index is within range
template <class T>
const T &GetProperty(const std::vector<T> &props, int idx)
{
if (idx >= props.size())
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
return props[idx];
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
PLYImporter::PLYImporter() PLYImporter::PLYImporter()
@ -431,13 +449,13 @@ void PLYImporter::LoadTextureCoordinates(std::vector<aiVector2D>* pvOut)
if (0xFFFFFFFF != aiPositions[0]) if (0xFFFFFFFF != aiPositions[0])
{ {
vOut.x = PLY::PropertyInstance::ConvertTo<float>( vOut.x = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]); GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
} }
if (0xFFFFFFFF != aiPositions[1]) if (0xFFFFFFFF != aiPositions[1])
{ {
vOut.y = PLY::PropertyInstance::ConvertTo<float>( vOut.y = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]); GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
} }
// and add them to our nice list // and add them to our nice list
pvOut->push_back(vOut); pvOut->push_back(vOut);
@ -541,19 +559,19 @@ void PLYImporter::LoadVertices(std::vector<aiVector3D>* pvOut, bool p_bNormals)
if (0xFFFFFFFF != aiPositions[0]) if (0xFFFFFFFF != aiPositions[0])
{ {
vOut.x = PLY::PropertyInstance::ConvertTo<float>( vOut.x = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]); GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
} }
if (0xFFFFFFFF != aiPositions[1]) if (0xFFFFFFFF != aiPositions[1])
{ {
vOut.y = PLY::PropertyInstance::ConvertTo<float>( vOut.y = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]); GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
} }
if (0xFFFFFFFF != aiPositions[2]) if (0xFFFFFFFF != aiPositions[2])
{ {
vOut.z = PLY::PropertyInstance::ConvertTo<float>( vOut.z = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[2]].avList.front(),aiTypes[2]); GetProperty((*i).alProperties, aiPositions[2]).avList.front(),aiTypes[2]);
} }
// and add them to our nice list // and add them to our nice list
@ -659,28 +677,28 @@ void PLYImporter::LoadVertexColor(std::vector<aiColor4D>* pvOut)
if (0xFFFFFFFF != aiPositions[0]) if (0xFFFFFFFF != aiPositions[0])
{ {
vOut.r = NormalizeColorValue((*i).alProperties[ vOut.r = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[0]].avList.front(),aiTypes[0]); aiPositions[0]).avList.front(),aiTypes[0]);
} }
if (0xFFFFFFFF != aiPositions[1]) if (0xFFFFFFFF != aiPositions[1])
{ {
vOut.g = NormalizeColorValue((*i).alProperties[ vOut.g = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[1]].avList.front(),aiTypes[1]); aiPositions[1]).avList.front(),aiTypes[1]);
} }
if (0xFFFFFFFF != aiPositions[2]) if (0xFFFFFFFF != aiPositions[2])
{ {
vOut.b = NormalizeColorValue((*i).alProperties[ vOut.b = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[2]].avList.front(),aiTypes[2]); aiPositions[2]).avList.front(),aiTypes[2]);
} }
// assume 1.0 for the alpha channel ifit is not set // assume 1.0 for the alpha channel ifit is not set
if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f; if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f;
else else
{ {
vOut.a = NormalizeColorValue((*i).alProperties[ vOut.a = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[3]].avList.front(),aiTypes[3]); aiPositions[3]).avList.front(),aiTypes[3]);
} }
// and add them to our nice list // and add them to our nice list
@ -773,11 +791,11 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
// parse the list of vertex indices // parse the list of vertex indices
if (0xFFFFFFFF != iProperty) if (0xFFFFFFFF != iProperty)
{ {
const unsigned int iNum = (unsigned int)(*i).alProperties[iProperty].avList.size(); const unsigned int iNum = (unsigned int)GetProperty((*i).alProperties, iProperty).avList.size();
sFace.mIndices.resize(iNum); sFace.mIndices.resize(iNum);
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p = std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
(*i).alProperties[iProperty].avList.begin(); GetProperty((*i).alProperties, iProperty).avList.begin();
for (unsigned int a = 0; a < iNum;++a,++p) for (unsigned int a = 0; a < iNum;++a,++p)
{ {
@ -789,7 +807,7 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
if (0xFFFFFFFF != iMaterialIndex) if (0xFFFFFFFF != iMaterialIndex)
{ {
sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>( sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>(
(*i).alProperties[iMaterialIndex].avList.front(),eType2); GetProperty((*i).alProperties, iMaterialIndex).avList.front(),eType2);
} }
pvOut->push_back(sFace); pvOut->push_back(sFace);
} }
@ -800,7 +818,7 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
// a value of -1 indicates a restart of the strip // a value of -1 indicates a restart of the strip
bool flip = false; bool flip = false;
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) { for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList; const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty((*i).alProperties, iProperty).avList;
pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
int aiTable[2] = {-1,-1}; int aiTable[2] = {-1,-1};
@ -851,30 +869,30 @@ void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance>& avL
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f; if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
else else
{ {
clrOut->r = NormalizeColorValue(avList[ clrOut->r = NormalizeColorValue(GetProperty(avList,
aiPositions[0]].avList.front(),aiTypes[0]); aiPositions[0]).avList.front(),aiTypes[0]);
} }
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f; if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
else else
{ {
clrOut->g = NormalizeColorValue(avList[ clrOut->g = NormalizeColorValue(GetProperty(avList,
aiPositions[1]].avList.front(),aiTypes[1]); aiPositions[1]).avList.front(),aiTypes[1]);
} }
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f; if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
else else
{ {
clrOut->b = NormalizeColorValue(avList[ clrOut->b = NormalizeColorValue(GetProperty(avList,
aiPositions[2]].avList.front(),aiTypes[2]); aiPositions[2]).avList.front(),aiTypes[2]);
} }
// assume 1.0 for the alpha channel ifit is not set // assume 1.0 for the alpha channel ifit is not set
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f; if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
else else
{ {
clrOut->a = NormalizeColorValue(avList[ clrOut->a = NormalizeColorValue(GetProperty(avList,
aiPositions[3]].avList.front(),aiTypes[3]); aiPositions[3]).avList.front(),aiTypes[3]);
} }
} }
@ -1025,7 +1043,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
// handle phong power and shading mode // handle phong power and shading mode
int iMode; int iMode;
if (0xFFFFFFFF != iPhong) { if (0xFFFFFFFF != iPhong) {
float fSpec = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),ePhong); float fSpec = PLY::PropertyInstance::ConvertTo<float>(GetProperty((*i).alProperties, iPhong).avList.front(),ePhong);
// if shininess is 0 (and the pow() calculation would therefore always // if shininess is 0 (and the pow() calculation would therefore always
// become 1, not depending on the angle), use gouraud lighting // become 1, not depending on the angle), use gouraud lighting
@ -1043,7 +1061,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
// handle opacity // handle opacity
if (0xFFFFFFFF != iOpacity) { if (0xFFFFFFFF != iOpacity) {
float fOpacity = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),eOpacity); float fOpacity = PLY::PropertyInstance::ConvertTo<float>(GetProperty((*i).alProperties, iPhong).avList.front(),eOpacity);
pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY); pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY);
} }