Add bounds checks to the parsing utilities. (#5421)
* Add bounds checks to the parsing utilities. * Fix merge conflicts in ACLoader. * Fix loaders * Fix unittest of AC-Loader. * Remove dead code. * Md5Parser fixes * Fix md5-parsing * Fix Merge conflict * Fix merge conflicts. * Md5: Fix warning: missing return statement.
This commit is contained in:
@@ -82,23 +82,20 @@ CSMImporter::CSMImporter() : noSkeletonMesh(){
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
||||
{
|
||||
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const {
|
||||
static const char* tokens[] = {"$Filename"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Build a string of all file extensions supported
|
||||
const aiImporterDesc* CSMImporter::GetInfo () const
|
||||
{
|
||||
const aiImporterDesc* CSMImporter::GetInfo () const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup configuration properties for the loader
|
||||
void CSMImporter::SetupProperties(const Importer* pImp)
|
||||
{
|
||||
void CSMImporter::SetupProperties(const Importer* pImp) {
|
||||
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
||||
}
|
||||
|
||||
@@ -118,29 +115,29 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
std::vector<char> mBuffer2;
|
||||
TextFileToBuffer(file.get(),mBuffer2);
|
||||
const char* buffer = &mBuffer2[0];
|
||||
|
||||
const char *end = &mBuffer2[mBuffer2.size() - 1] + 1;
|
||||
std::unique_ptr<aiAnimation> anim(new aiAnimation());
|
||||
int first = 0, last = 0x00ffffff;
|
||||
|
||||
// now process the file and look out for '$' sections
|
||||
while (true) {
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
if ('\0' == *buffer)
|
||||
break;
|
||||
|
||||
if ('$' == *buffer) {
|
||||
++buffer;
|
||||
if (TokenMatchI(buffer,"firstframe",10)) {
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
first = strtol10(buffer,&buffer);
|
||||
}
|
||||
else if (TokenMatchI(buffer,"lastframe",9)) {
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
last = strtol10(buffer,&buffer);
|
||||
}
|
||||
else if (TokenMatchI(buffer,"rate",4)) {
|
||||
SkipSpaces(&buffer);
|
||||
float d;
|
||||
SkipSpaces(&buffer, end);
|
||||
float d = { 0.0f };
|
||||
buffer = fast_atoreal_move<float>(buffer,d);
|
||||
anim->mTicksPerSecond = d;
|
||||
}
|
||||
@@ -148,8 +145,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
std::vector< aiNodeAnim* > anims_temp;
|
||||
anims_temp.reserve(30);
|
||||
while (true) {
|
||||
SkipSpaces(&buffer);
|
||||
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
|
||||
SkipSpaces(&buffer, end);
|
||||
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer, end) && *buffer == '$')
|
||||
break; // next section
|
||||
|
||||
// Construct a new node animation channel and setup its name
|
||||
@@ -157,41 +154,43 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
aiNodeAnim* nda = anims_temp.back();
|
||||
|
||||
char* ot = nda->mNodeName.data;
|
||||
while (!IsSpaceOrNewLine(*buffer))
|
||||
while (!IsSpaceOrNewLine(*buffer)) {
|
||||
*ot++ = *buffer++;
|
||||
}
|
||||
|
||||
*ot = '\0';
|
||||
nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
|
||||
}
|
||||
|
||||
anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
|
||||
if (!anim->mNumChannels)
|
||||
if (!anim->mNumChannels) {
|
||||
throw DeadlyImportError("CSM: Empty $order section");
|
||||
}
|
||||
|
||||
// copy over to the output animation
|
||||
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
||||
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
|
||||
}
|
||||
else if (TokenMatchI(buffer,"points",6)) {
|
||||
if (!anim->mNumChannels)
|
||||
} else if (TokenMatchI(buffer,"points",6)) {
|
||||
if (!anim->mNumChannels) {
|
||||
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
|
||||
}
|
||||
|
||||
// If we know how many frames we'll read, we can preallocate some storage
|
||||
unsigned int alloc = 100;
|
||||
if (last != 0x00ffffff)
|
||||
{
|
||||
if (last != 0x00ffffff) {
|
||||
alloc = last-first;
|
||||
alloc += alloc>>2u; // + 25%
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i)
|
||||
for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
|
||||
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int filled = 0;
|
||||
|
||||
// Now read all point data.
|
||||
while (true) {
|
||||
SkipSpaces(&buffer);
|
||||
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
|
||||
SkipSpaces(&buffer, end);
|
||||
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer, end) || *buffer == '$')) {
|
||||
break; // next section
|
||||
}
|
||||
|
||||
@@ -202,8 +201,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
|
||||
aiNodeAnim* s = anim->mChannels[i];
|
||||
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
|
||||
|
||||
if (s->mNumPositionKeys == alloc) {
|
||||
// need to reallocate?
|
||||
aiVectorKey* old = s->mPositionKeys;
|
||||
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
|
||||
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
|
||||
@@ -211,24 +210,26 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
}
|
||||
|
||||
// read x,y,z
|
||||
if(!SkipSpacesAndLineEnd(&buffer))
|
||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord");
|
||||
}
|
||||
|
||||
if (TokenMatchI(buffer, "DROPOUT", 7)) {
|
||||
// seems this is invalid marker data; at least the doc says it's possible
|
||||
ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
|
||||
sub->mTime = (double)frame;
|
||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
|
||||
|
||||
if(!SkipSpacesAndLineEnd(&buffer))
|
||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
|
||||
}
|
||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
|
||||
|
||||
if(!SkipSpacesAndLineEnd(&buffer))
|
||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
|
||||
}
|
||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
|
||||
|
||||
++s->mNumPositionKeys;
|
||||
@@ -236,22 +237,22 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
}
|
||||
|
||||
// update allocation granularity
|
||||
if (filled == alloc)
|
||||
if (filled == alloc) {
|
||||
alloc *= 2;
|
||||
}
|
||||
|
||||
++filled;
|
||||
}
|
||||
// all channels must be complete in order to continue safely.
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
|
||||
if (!anim->mChannels[i]->mNumPositionKeys)
|
||||
if (!anim->mChannels[i]->mNumPositionKeys) {
|
||||
throw DeadlyImportError("CSM: Invalid marker track");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// advance to the next line
|
||||
SkipLine(&buffer);
|
||||
SkipLine(&buffer, end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +266,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
pScene->mRootNode->mNumChildren = anim->mNumChannels;
|
||||
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
|
||||
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
aiNodeAnim* na = anim->mChannels[i];
|
||||
|
||||
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
|
||||
|
||||
Reference in New Issue
Block a user