starmath/inc/parse.hxx           |   18 +++++
 starmath/source/mathmlimport.cxx |   17 +++--
 starmath/source/parse.cxx        |  122 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 150 insertions(+), 7 deletions(-)

New commits:
commit 1a658831d86f6dba67f8f3bcd47435d496fe4dfa
Author: Caolán McNamara <caol...@redhat.com>
Date:   Wed Dec 6 10:38:38 2017 +0000

    ofz#4539 depth protect mathtype parser
    
    Change-Id: I46e12f52d56e7802b676309207904b4d1894d236
    Reviewed-on: https://gerrit.libreoffice.org/45928
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    Tested-by: Caolán McNamara <caol...@redhat.com>

diff --git a/starmath/inc/parse.hxx b/starmath/inc/parse.hxx
index 1bcef035d5b2..5d1eeef553d4 100644
--- a/starmath/inc/parse.hxx
+++ b/starmath/inc/parse.hxx
@@ -41,6 +41,24 @@ class SmParser
                     m_nColOff; // 0-based
     bool            m_bImportSymNames,
                     m_bExportSymNames;
+    sal_Int32       m_nParseDepth;
+
+    class DepthProtect
+    {
+    private:
+        sal_Int32& m_rParseDepth;
+    public:
+        DepthProtect(sal_Int32& rParseDepth)
+            : m_rParseDepth(rParseDepth)
+        {
+            ++m_rParseDepth;
+        }
+        bool TooDeep() const { return m_rParseDepth > 2048; }
+        ~DepthProtect()
+        {
+            --m_rParseDepth;
+        }
+    };
 
     // map of used symbols (used to reduce file size by exporting only 
actually used symbols)
     std::set< OUString >   m_aUsedSymbols;
diff --git a/starmath/source/mathmlimport.cxx b/starmath/source/mathmlimport.cxx
index 87befa6fdc85..3697f23b3c4d 100644
--- a/starmath/source/mathmlimport.cxx
+++ b/starmath/source/mathmlimport.cxx
@@ -297,11 +297,11 @@ ErrCode SmXMLImportWrapper::ReadThroughComponent(
         if ( pFilter && pFilter->GetSuccess() )
             nError = ERRCODE_NONE;
     }
-    catch( xml::sax::SAXParseException& r )
+    catch (const xml::sax::SAXParseException& r)
     {
         // sax parser sends wrapped exceptions,
         // try to find the original one
-        xml::sax::SAXException aSaxEx = 
*static_cast<xml::sax::SAXException*>(&r);
+        xml::sax::SAXException aSaxEx = *static_cast<const 
xml::sax::SAXException*>(&r);
         bool bTryChild = true;
 
         while( bTryChild )
@@ -320,7 +320,7 @@ ErrCode SmXMLImportWrapper::ReadThroughComponent(
         if ( bEncrypted )
             nError = ERRCODE_SFX_WRONGPASSWORD;
     }
-    catch( const xml::sax::SAXException& r )
+    catch (const xml::sax::SAXException& r)
     {
         packages::zip::ZipIOException aBrokenPackage;
         if ( r.WrappedException >>= aBrokenPackage )
@@ -329,11 +329,14 @@ ErrCode SmXMLImportWrapper::ReadThroughComponent(
         if ( bEncrypted )
             nError = ERRCODE_SFX_WRONGPASSWORD;
     }
-    catch( packages::zip::ZipIOException& )
+    catch (const packages::zip::ZipIOException&)
     {
         nError = ERRCODE_IO_BROKENPACKAGE;
     }
-    catch( io::IOException& )
+    catch (const io::IOException&)
+    {
+    }
+    catch (const std::range_error&)
     {
     }
 
@@ -3131,7 +3134,9 @@ extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL 
TestImportMML(SvStream &rStream)
     //to update the properties, which throws cause the properties are 
uninitialized
     xDocSh->SetLoading(SfxLoadedFlags::NONE);
 
-    auto nRet = SmXMLImportWrapper::ReadThroughComponent(xStream, xModel, 
xContext, xInfoSet, "com.sun.star.comp.Math.XMLImporter", false);
+    ErrCode nRet = ERRCODE_SFX_DOLOADFAILED;
+
+    nRet = SmXMLImportWrapper::ReadThroughComponent(xStream, xModel, xContext, 
xInfoSet, "com.sun.star.comp.Math.XMLImporter", false);
 
     xDocSh->SetLoading(SfxLoadedFlags::ALL);
 
diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx
index b920fc871130..92dca7b025a1 100644
--- a/starmath/source/parse.cxx
+++ b/starmath/source/parse.cxx
@@ -940,6 +940,10 @@ void SmParser::NextToken()
 
 SmTableNode *SmParser::DoTable()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     SmNodeArray aLineArray;
     aLineArray.push_back(DoLine());
     while (m_aCurToken.eType == TNEWLINE)
@@ -956,6 +960,10 @@ SmTableNode *SmParser::DoTable()
 SmNode *SmParser::DoAlign(bool bUseExtraSpaces)
     // parse alignment info (if any), then go on with rest of expression
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     std::unique_ptr<SmStructureNode> pSNode;
 
     if (TokenInGroup(TG::Align))
@@ -982,6 +990,10 @@ SmNode *SmParser::DoAlign(bool bUseExtraSpaces)
 // Postcondition: m_aCurToken.eType == TEND || m_aCurToken.eType == TNEWLINE
 SmLineNode *SmParser::DoLine()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     SmNodeArray  ExpressionArray;
 
     // start with single expression that may have an alignment statement
@@ -1010,6 +1022,10 @@ SmLineNode *SmParser::DoLine()
 
 SmNode *SmParser::DoExpression(bool bUseExtraSpaces)
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     SmNodeArray  RelationArray;
     RelationArray.push_back(DoRelation());
     while (m_aCurToken.nLevel >= 4)
@@ -1031,6 +1047,10 @@ SmNode *SmParser::DoExpression(bool bUseExtraSpaces)
 
 SmNode *SmParser::DoRelation()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     SmNode *pFirst = DoSum();
     while (TokenInGroup(TG::Relation))
     {
@@ -1045,6 +1065,10 @@ SmNode *SmParser::DoRelation()
 
 SmNode *SmParser::DoSum()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     SmNode *pFirst = DoProduct();
     while (TokenInGroup(TG::Sum))
     {
@@ -1059,6 +1083,10 @@ SmNode *SmParser::DoSum()
 
 SmNode *SmParser::DoProduct()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     SmNode *pFirst = DoPower();
 
     while (TokenInGroup(TG::Product))
@@ -1132,6 +1160,10 @@ SmNode *SmParser::DoProduct()
 
 SmNode *SmParser::DoSubSup(TG nActiveGroup, SmNode *pGivenNode)
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(nActiveGroup == TG::Power || nActiveGroup == TG::Limit);
     assert(m_aCurToken.nGroup == nActiveGroup);
 
@@ -1202,6 +1234,10 @@ SmNode *SmParser::DoSubSup(TG nActiveGroup, SmNode 
*pGivenNode)
 
 SmNode *SmParser::DoOpSubSup()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     // get operator symbol
     auto pNode = o3tl::make_unique<SmMathSymbolNode>(m_aCurToken);
     // skip operator token
@@ -1214,6 +1250,10 @@ SmNode *SmParser::DoOpSubSup()
 
 SmNode *SmParser::DoPower()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     // get body for sub- supscripts on top of stack
     SmNode *pNode = DoTerm(false);
 
@@ -1224,6 +1264,10 @@ SmNode *SmParser::DoPower()
 
 SmBlankNode *SmParser::DoBlank()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(TokenInGroup(TG::Blank));
     std::unique_ptr<SmBlankNode> pBlankNode(new SmBlankNode(m_aCurToken));
 
@@ -1245,6 +1289,10 @@ SmBlankNode *SmParser::DoBlank()
 
 SmNode *SmParser::DoTerm(bool bGroupNumberIdent)
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     switch (m_aCurToken.eType)
     {
         case TESCAPE :
@@ -1454,6 +1502,10 @@ SmNode *SmParser::DoTerm(bool bGroupNumberIdent)
 
 SmNode *SmParser::DoEscape()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     NextToken();
 
     switch (m_aCurToken.eType)
@@ -1490,6 +1542,10 @@ SmNode *SmParser::DoEscape()
 
 SmOperNode *SmParser::DoOperator()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(TokenInGroup(TG::Oper));
 
     auto pSNode = o3tl::make_unique<SmOperNode>(m_aCurToken);
@@ -1510,6 +1566,10 @@ SmOperNode *SmParser::DoOperator()
 
 SmNode *SmParser::DoOper()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     SmTokenType  eType (m_aCurToken.eType);
     std::unique_ptr<SmNode> pNode;
 
@@ -1564,6 +1624,10 @@ SmNode *SmParser::DoOper()
 
 SmStructureNode *SmParser::DoUnOper()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(TokenInGroup(TG::UnOper));
 
     SmToken      aNodeToken = m_aCurToken;
@@ -1649,6 +1713,10 @@ SmStructureNode *SmParser::DoUnOper()
 
 SmAttributNode *SmParser::DoAttribut()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(TokenInGroup(TG::Attribute));
 
     auto pSNode = o3tl::make_unique<SmAttributNode>(m_aCurToken);
@@ -1682,9 +1750,12 @@ SmAttributNode *SmParser::DoAttribut()
     return pSNode.release();
 }
 
-
 SmStructureNode *SmParser::DoFontAttribut()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(TokenInGroup(TG::FontAttr));
 
     switch (m_aCurToken.eType)
@@ -1717,6 +1788,10 @@ SmStructureNode *SmParser::DoFontAttribut()
 
 SmStructureNode *SmParser::DoColor()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(m_aCurToken.eType == TCOLOR);
 
     // last color rules, get that one
@@ -1737,6 +1812,10 @@ SmStructureNode *SmParser::DoColor()
 
 SmStructureNode *SmParser::DoFont()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(m_aCurToken.eType == TFONT);
 
     // last font rules, get that one
@@ -1780,6 +1859,10 @@ static bool lcl_IsNumber(const OUString& rText)
 
 SmStructureNode *SmParser::DoFontSize()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(m_aCurToken.eType == TSIZE);
 
     FontSizeType   Type;
@@ -1842,6 +1925,10 @@ SmStructureNode *SmParser::DoFontSize()
 
 SmStructureNode *SmParser::DoBrace()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     assert(m_aCurToken.eType == TLEFT  ||  TokenInGroup(TG::LBrace));
 
     std::unique_ptr<SmStructureNode> pSNode(new SmBraceNode(m_aCurToken));
@@ -1926,6 +2013,10 @@ SmStructureNode *SmParser::DoBrace()
 
 SmBracebodyNode *SmParser::DoBracebody(bool bIsLeftRight)
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     auto pBody = o3tl::make_unique<SmBracebodyNode>(m_aCurToken);
     SmNodeArray aNodes;
     // get body if any
@@ -1971,6 +2062,10 @@ SmBracebodyNode *SmParser::DoBracebody(bool bIsLeftRight)
 
 SmTextNode *SmParser::DoFunction()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     switch (m_aCurToken.eType)
     {
         case TFUNC:
@@ -2010,6 +2105,10 @@ SmTextNode *SmParser::DoFunction()
 
 SmTableNode *SmParser::DoBinom()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     auto pSNode = o3tl::make_unique<SmTableNode>(m_aCurToken);
 
     NextToken();
@@ -2022,6 +2121,10 @@ SmTableNode *SmParser::DoBinom()
 
 SmStructureNode *SmParser::DoStack()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     std::unique_ptr<SmStructureNode> pSNode(new SmTableNode(m_aCurToken));
     NextToken();
     if (m_aCurToken.eType != TLGROUP)
@@ -2045,6 +2148,10 @@ SmStructureNode *SmParser::DoStack()
 
 SmStructureNode *SmParser::DoMatrix()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     std::unique_ptr<SmMatrixNode> pMNode(new SmMatrixNode(m_aCurToken));
     NextToken();
     if (m_aCurToken.eType != TLGROUP)
@@ -2101,6 +2208,10 @@ SmStructureNode *SmParser::DoMatrix()
 
 SmSpecialNode *SmParser::DoSpecial()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     bool bReplace = false;
     OUString &rName = m_aCurToken.aText;
     OUString aNewName;
@@ -2143,6 +2254,10 @@ SmSpecialNode *SmParser::DoSpecial()
 
 SmGlyphSpecialNode *SmParser::DoGlyphSpecial()
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     auto pNode = o3tl::make_unique<SmGlyphSpecialNode>(m_aCurToken);
     NextToken();
     return pNode.release();
@@ -2150,6 +2265,10 @@ SmGlyphSpecialNode *SmParser::DoGlyphSpecial()
 
 SmExpressionNode *SmParser::DoError(SmParseError eError)
 {
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep())
+        throw std::range_error("parser depth limit");
+
     auto pSNode = o3tl::make_unique<SmExpressionNode>(m_aCurToken);
     SmErrorNode     *pErr   = new SmErrorNode(m_aCurToken);
     pSNode->SetSubNodes(pErr, nullptr);
@@ -2172,6 +2291,7 @@ SmParser::SmParser()
     , m_nColOff( 0 )
     , m_bImportSymNames( false )
     , m_bExportSymNames( false )
+    , m_nParseDepth(0)
     , m_aNumCC( LanguageTag( LANGUAGE_ENGLISH_US ) )
     , m_pSysCC( SM_MOD()->GetSysLocale().GetCharClassPtr() )
 {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to