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:
Kim Kulling
2024-01-30 14:32:41 +01:00
committed by GitHub
parent d5f35582d4
commit c08e3b4abb
39 changed files with 853 additions and 782 deletions

View File

@@ -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();