summaryrefslogtreecommitdiff
path: root/starmath
diff options
context:
space:
mode:
authorTakeshi Abe <tabe@fixedpoint.jp>2017-03-23 18:45:38 +0900
committerTakeshi Abe <tabe@fixedpoint.jp>2017-03-23 13:42:53 +0000
commit42870930e2a625766288edc3ba956c1bcac198f0 (patch)
tree7c5f29de62cdef5bb1e9d56fb1586d38b0f0a9f5 /starmath
parentb755c56c50cffb1e61c448dd34d54475e4993390 (diff)
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 <ci@libreoffice.org> Reviewed-by: Takeshi Abe <tabe@fixedpoint.jp>
Diffstat (limited to 'starmath')
-rw-r--r--starmath/source/parse.cxx42
1 files 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<int>(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<SmNode> 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<SmNode> 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);