git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@903 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2011-02-20 00:01:52 +00:00
parent 79eca6196d
commit 94767ecf8c
9 changed files with 80 additions and 41 deletions

View File

@@ -91,7 +91,7 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
// set up memory pointers
P = &pBuffer.front();
End = P + pBuffer.size();
End = P + pBuffer.size() - 1;
// check header
if( strncmp( P, "xof ", 4) != 0)
@@ -180,7 +180,8 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
// First find out how much storage we'll need. Count sections.
const char* P1 = P;
unsigned int est_out = 0;
while (P1 < End)
while (P1 + 3 < End)
{
// read next offset
uint16_t ofs = *((uint16_t*)P1);
@@ -199,12 +200,16 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
// and advance to the next offset
P1 += ofs;
est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size
// this block would continue past the file end, abort
if (P1 > End)
throw DeadlyImportError("X: Unexpected end of file while uncompressing");
}
// Allocate storage and do the actual uncompressing
uncompressed.resize(est_out);
// Allocate storage and terminating zero and do the actual uncompressing
uncompressed.resize(est_out + 1);
char* out = &uncompressed.front();
while (P < End)
while (P + 3 < End)
{
uint16_t ofs = *((uint16_t*)P);
AI_SWAP2(ofs);
@@ -592,6 +597,9 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
{
readHeadOfDataObject();
if( pMesh->mNumTextures + 1 > AI_MAX_NUMBER_OF_TEXTURECOORDS)
ThrowException( "Too many sets of texture coordinates");
std::vector<aiVector2D>& coords = pMesh->mTexCoords[pMesh->mNumTextures++];
unsigned int numCoords = ReadInt();
@@ -609,6 +617,8 @@ void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
{
readHeadOfDataObject();
if( pMesh->mNumColorSets + 1 > AI_MAX_NUMBER_OF_COLOR_SETS)
ThrowException( "Too many colorsets");
std::vector<aiColor4D>& colors = pMesh->mColors[pMesh->mNumColorSets++];
unsigned int numColors = ReadInt();
@@ -659,7 +669,7 @@ void XFileParser::ParseDataObjectMeshMaterialList( Mesh* pMesh)
// commented out version check, as version 03.03 exported from blender also has 2 semicolons
if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
{
if( *P == ';')
if(P < End && *P == ';')
++P;
}
@@ -1043,6 +1053,7 @@ std::string XFileParser::GetNextToken()
// in binary mode it will only return NAME and STRING token
// and (correctly) skip over other tokens.
if( End - P < 2) return s;
unsigned int tok = ReadBinWord();
unsigned int len;
@@ -1051,13 +1062,17 @@ std::string XFileParser::GetNextToken()
{
case 1:
// name token
if( End - P < 4) return s;
len = ReadBinDWord();
if( End - P < len) return s;
s = std::string(P, len);
P += len;
return s;
case 2:
// string token
if( End - P < 4) return s;
len = ReadBinDWord();
if( End - P < len) return s;
s = std::string(P, len);
P += (len + 2);
return s;
@@ -1070,10 +1085,12 @@ std::string XFileParser::GetNextToken()
P += 16;
return "<guid>";
case 6:
if( End - P < 4) return s;
len = ReadBinDWord();
P += (len * 4);
return "<int_list>";
case 7:
if( End - P < 4) return s;
len = ReadBinDWord();
P += (len * mBinaryFloatSize);
return "<flt_list>";
@@ -1227,6 +1244,7 @@ void XFileParser::ReadUntilEndOfLine()
// ------------------------------------------------------------------------------------------------
unsigned short XFileParser::ReadBinWord()
{
assert(End - P >= 2);
const unsigned char* q = (const unsigned char*) P;
unsigned short tmp = q[0] | (q[1] << 8);
P += 2;
@@ -1236,6 +1254,7 @@ unsigned short XFileParser::ReadBinWord()
// ------------------------------------------------------------------------------------------------
unsigned int XFileParser::ReadBinDWord()
{
assert(End - P >= 4);
const unsigned char* q = (const unsigned char*) P;
unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
P += 4;
@@ -1247,17 +1266,22 @@ unsigned int XFileParser::ReadInt()
{
if( mIsBinaryFormat)
{
if( mBinaryNumCount == 0)
if( mBinaryNumCount == 0 && End - P >= 2)
{
unsigned short tmp = ReadBinWord(); // 0x06 or 0x03
if( tmp == 0x06) // array of ints follows
if( tmp == 0x06 && End - P >= 4) // array of ints follows
mBinaryNumCount = ReadBinDWord();
else // single int follows
mBinaryNumCount = 1;
}
--mBinaryNumCount;
return ReadBinDWord();
if ( End - P >= 4) {
return ReadBinDWord();
} else {
P = End;
return 0;
}
} else
{
FindNextNoneWhiteSpace();
@@ -1296,10 +1320,10 @@ float XFileParser::ReadFloat()
{
if( mIsBinaryFormat)
{
if( mBinaryNumCount == 0)
if( mBinaryNumCount == 0 && End - P >= 2)
{
unsigned short tmp = ReadBinWord(); // 0x07 or 0x42
if( tmp == 0x07) // array of floats following
if( tmp == 0x07 && End - P >= 4) // array of floats following
mBinaryNumCount = ReadBinDWord();
else // single float following
mBinaryNumCount = 1;
@@ -1308,14 +1332,24 @@ float XFileParser::ReadFloat()
--mBinaryNumCount;
if( mBinaryFloatSize == 8)
{
float result = (float) (*(double*) P);
P += 8;
return result;
if( End - P >= 8) {
float result = (float) (*(double*) P);
P += 8;
return result;
} else {
P = End;
return 0;
}
} else
{
float result = *(float*) P;
P += 4;
return result;
if( End - P >= 4) {
float result = *(float*) P;
P += 4;
return result;
} else {
P = End;
return 0;
}
}
}
@@ -1323,6 +1357,7 @@ float XFileParser::ReadFloat()
FindNextNoneWhiteSpace();
// check for various special strings to allow reading files from faulty exporters
// I mean you, Blender!
// Reading is safe because of the terminating zero
if( strncmp( P, "-1.#IND00", 9) == 0 || strncmp( P, "1.#IND00", 8) == 0)
{
P += 9;