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

@@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <utility>
using namespace Assimp;
namespace Assimp {
// ------------------------------------------------------------------------------------------------
PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) {
@@ -296,7 +296,7 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
return true;
}
//parse the number of occurrences of this element
// parse the number of occurrences of this element
const char *pCur = (char *)&buffer[0];
pOut->NumOccur = strtoul10(pCur, &pCur);
@@ -321,13 +321,13 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
return true;
}
// ------------------------------------------------------------------------------------------------
bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
ret = Assimp::SkipSpaces(pCur, &pCur);
ret = Assimp::SkipSpaces(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@@ -339,10 +339,11 @@ bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
bool PLY::DOM::SkipLine(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
ret = Assimp::SkipLine(pCur, &pCur);
ret = Assimp::SkipLine(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@@ -369,10 +370,11 @@ bool PLY::DOM::TokenMatch(std::vector<char> &buffer, const char *token, unsigned
bool PLY::DOM::SkipSpacesAndLineEnd(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur);
ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@@ -426,7 +428,7 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char>
} else {
// ignore unknown header elements
if (!streamBuffer.getNextLine(buffer))
return false;
return false;
}
}
@@ -446,7 +448,7 @@ bool PLY::DOM::ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std
std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
// parse all element instances
//construct vertices and faces
// construct vertices and faces
for (; i != alElements.end(); ++i, ++a) {
if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip) {
PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), nullptr, loader);
@@ -528,7 +530,7 @@ bool PLY::DOM::ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM *p_pcOut, P
return false;
}
//get next line after header
// get next line after header
streamBuffer.getNextLine(buffer);
if (!p_pcOut->ParseElementInstanceLists(streamBuffer, buffer, loader)) {
ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() failure");
@@ -558,23 +560,24 @@ bool PLY::ElementInstanceList::ParseInstanceList(
}
} else {
const char *pCur = (const char *)&buffer[0];
const char *end = pCur + buffer.size();
// be sure to have enough storage
for (unsigned int i = 0; i < pcElement->NumOccur; ++i) {
if (p_pcOut)
PLY::ElementInstance::ParseInstance(pCur, pcElement, &p_pcOut->alInstances[i]);
PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &p_pcOut->alInstances[i]);
else {
ElementInstance elt;
PLY::ElementInstance::ParseInstance(pCur, pcElement, &elt);
PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &elt);
// Create vertex or face
if (pcElement->eSemantic == EEST_Vertex) {
//call loader instance from here
// call loader instance from here
loader->LoadVertex(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_Face) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_TriStrip) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
}
}
@@ -611,13 +614,13 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
// Create vertex or face
if (pcElement->eSemantic == EEST_Vertex) {
//call loader instance from here
// call loader instance from here
loader->LoadVertex(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_Face) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_TriStrip) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
}
}
@@ -626,7 +629,7 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
}
// ------------------------------------------------------------------------------------------------
bool PLY::ElementInstance::ParseInstance(const char *&pCur,
bool PLY::ElementInstance::ParseInstance(const char *&pCur, const char *end,
const PLY::Element *pcElement,
PLY::ElementInstance *p_pcOut) {
ai_assert(nullptr != pcElement);
@@ -638,7 +641,7 @@ bool PLY::ElementInstance::ParseInstance(const char *&pCur,
std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
for (; i != p_pcOut->alProperties.end(); ++i, ++a) {
if (!(PLY::PropertyInstance::ParseInstance(pCur, &(*a), &(*i)))) {
if (!(PLY::PropertyInstance::ParseInstance(pCur, end, &(*a), &(*i)))) {
ASSIMP_LOG_WARN("Unable to parse property instance. "
"Skipping this element instance");
@@ -678,13 +681,13 @@ bool PLY::ElementInstance::ParseInstanceBinary(
}
// ------------------------------------------------------------------------------------------------
bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
const PLY::Property *prop, PLY::PropertyInstance *p_pcOut) {
bool PLY::PropertyInstance::ParseInstance(const char *&pCur, const char *end, const PLY::Property *prop,
PLY::PropertyInstance *p_pcOut) {
ai_assert(nullptr != prop);
ai_assert(nullptr != p_pcOut);
// skip spaces at the beginning
if (!SkipSpaces(&pCur)) {
if (!SkipSpaces(&pCur, end)) {
return false;
}
@@ -699,7 +702,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
// parse all list elements
p_pcOut->avList.resize(iNum);
for (unsigned int i = 0; i < iNum; ++i) {
if (!SkipSpaces(&pCur))
if (!SkipSpaces(&pCur, end))
return false;
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &p_pcOut->avList[i]);
@@ -711,7 +714,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &v);
p_pcOut->avList.push_back(v);
}
SkipSpacesAndLineEnd(&pCur);
SkipSpacesAndLineEnd(&pCur, end);
return true;
}
@@ -774,7 +777,7 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
ai_assert(nullptr != pCur);
ai_assert(nullptr != out);
//calc element size
// calc element size
bool ret = true;
switch (eType) {
case EDT_UInt:
@@ -824,7 +827,7 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
bool p_bBE) {
ai_assert(nullptr != out);
//calc element size
// calc element size
unsigned int lsize = 0;
switch (eType) {
case EDT_Char:
@@ -852,11 +855,11 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
break;
}
//read the next file block if needed
// read the next file block if needed
if (bufferSize < lsize) {
std::vector<char> nbuffer;
if (streamBuffer.getNextBlock(nbuffer)) {
//concat buffer contents
// concat buffer contents
buffer = std::vector<char>(buffer.end() - bufferSize, buffer.end());
buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
nbuffer.clear();
@@ -958,4 +961,6 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
return ret;
}
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER