Skip to content

Commit

Permalink
XERCESC-2241 - Integer overflows in DFAContentModel class
Browse files Browse the repository at this point in the history
  • Loading branch information
scantor authored and Guilhem Moulin committed Dec 28, 2023
1 parent 2b1aa30 commit ec012e4
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions src/xercesc/validators/common/DFAContentModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/RuntimeException.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/framework/XMLElementDecl.hpp>
#include <xercesc/framework/XMLValidator.hpp>
Expand All @@ -41,6 +42,7 @@
#include <xercesc/util/RefHashTableOf.hpp>
#include <xercesc/util/XMLInteger.hpp>
#include <math.h>
#include <limits>

XERCES_CPP_NAMESPACE_BEGIN

Expand Down Expand Up @@ -606,8 +608,15 @@ void DFAContentModel::buildDFA(ContentSpecNode* const curNode)
// in the fLeafCount member.
//
fLeafCount=countLeafNodes(curNode);
// Avoid integer overflow in below fLeafCount++ increment
if (fLeafCount > (std::numeric_limits<unsigned int>::max() - 1))
throw OutOfMemoryException();
fEOCPos = fLeafCount++;

// Avoid integer overflow in below memory allocation
if (fLeafCount > (std::numeric_limits<size_t>::max() / sizeof(CMLeaf*)))
throw OutOfMemoryException();

// We need to build an array of references to the non-epsilon
// leaf nodes. We will put them in the array according to their position values
//
Expand Down Expand Up @@ -1304,14 +1313,27 @@ unsigned int DFAContentModel::countLeafNodes(ContentSpecNode* const curNode)
if(nLoopCount!=0)
{
count += countLeafNodes(cursor);
for(unsigned int i=0;i<nLoopCount;i++)
count += countLeafNodes(rightNode);
const unsigned int countRight = countLeafNodes(rightNode);
// Avoid integer overflow in below multiplication
if (countRight > (std::numeric_limits<unsigned int>::max() / nLoopCount))
throw OutOfMemoryException();
const unsigned int countRightMulLoopCount = nLoopCount * countRight;
// Avoid integer overflow in below addition
if (count > (std::numeric_limits<unsigned int>::max() - countRightMulLoopCount))
throw OutOfMemoryException();
count += countRightMulLoopCount;
return count;
}
if(leftNode)
count+=countLeafNodes(leftNode);
if(rightNode)
count+=countLeafNodes(rightNode);
{
const unsigned int countRight = countLeafNodes(rightNode);
// Avoid integer overflow in below addition
if (count > (std::numeric_limits<unsigned int>::max() - countRight))
throw OutOfMemoryException();
count+=countRight;
}
}
return count;
}
Expand Down

0 comments on commit ec012e4

Please sign in to comment.