From 42870930e2a625766288edc3ba956c1bcac198f0 Mon Sep 17 00:00:00 2001 From: Takeshi Abe Date: Thu, 23 Mar 2017 18:45:38 +0900 Subject: starmath: Fix memory leak at double sub/superscripts and avoid skipping following tokens too much. This also saves unnecessary stack operations. Change-Id: I4f30be73a615341b2b3de70f2c8f3dd5c2f85910 Reviewed-on: https://gerrit.libreoffice.org/35583 Tested-by: Jenkins Reviewed-by: Takeshi Abe --- starmath/source/parse.cxx | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx index 07383f3e359e..4ba51289bf1b 100644 --- a/starmath/source/parse.cxx +++ b/starmath/source/parse.cxx @@ -1178,18 +1178,6 @@ SmNode *SmParser::DoSubSup(TG nActiveGroup, SmNode *pGivenNode) while (TokenInGroup(nActiveGroup)) { SmTokenType eType (m_aCurToken.eType); - // skip sub-/supscript token - NextToken(); - - // get sub-/supscript node on top of stack - if (eType == TFROM || eType == TTO) - { - // parse limits in old 4.0 and 5.0 style - m_aNodeStack.emplace_front(DoRelation()); - } - else - m_aNodeStack.emplace_front(DoTerm(true)); - switch (eType) { case TRSUB : nIndex = static_cast(RSUB); break; @@ -1206,10 +1194,32 @@ SmNode *SmParser::DoSubSup(TG nActiveGroup, SmNode *pGivenNode) nIndex++; assert(1 <= nIndex && nIndex <= SUBSUP_NUM_ENTRIES); - // set sub-/supscript if not already done - if (aSubNodes[nIndex] != nullptr) - Error(SmParseError::DoubleSubsupscript); - aSubNodes[nIndex] = popOrZero(m_aNodeStack); + std::unique_ptr pENode; + if (aSubNodes[nIndex]) // if already occupied at earlier iteration + { + // forget the earlier one, remember an error instead + delete aSubNodes[nIndex]; + pENode.reset(DoError(SmParseError::DoubleSubsupscript)); // this also skips current token. + } + else + { + // skip sub-/supscript token + NextToken(); + } + + // get sub-/supscript node + // (even when we saw a double-sub/supscript error in the above + // in order to minimize mess and continue parsing.) + std::unique_ptr pSNode; + if (eType == TFROM || eType == TTO) + { + // parse limits in old 4.0 and 5.0 style + pSNode.reset(DoRelation()); + } + else + pSNode.reset(DoTerm(true)); + + aSubNodes[nIndex] = (pENode) ? pENode.release() : pSNode.release(); } pNode->SetSubNodes(aSubNodes); -- cgit