From 66d16b51f0822ae9945e0baa393543a7163614b5 Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Sat, 10 Feb 2018 14:39:57 +0100 Subject: [PATCH] Ticket #8352: Properly detect AST cycles. (#1060) --- lib/token.cpp | 8 ++++---- test/testgarbage.cpp | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 71e320908..24a80d055 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1078,13 +1078,13 @@ std::string Token::stringifyList(bool varid) const void Token::astOperand1(Token *tok) { - const Token* const root = tok; if (_astOperand1) _astOperand1->_astParent = nullptr; // goto parent operator if (tok) { + std::set visitedParents; while (tok->_astParent) { - if (tok->_astParent == this || tok->_astParent == root) // #6838/#6726 avoid hang on garbage code + if (!visitedParents.insert(tok->_astParent).second) // #6838/#6726/#8352 avoid hang on garbage code throw InternalError(this, "Internal error. Token::astOperand1() cyclic dependency."); tok = tok->_astParent; } @@ -1095,14 +1095,14 @@ void Token::astOperand1(Token *tok) void Token::astOperand2(Token *tok) { - const Token* const root = tok; if (_astOperand2) _astOperand2->_astParent = nullptr; // goto parent operator if (tok) { + std::set visitedParents; while (tok->_astParent) { //std::cout << tok << " -> " << tok->_astParent ; - if (tok->_astParent == this || tok->_astParent == root) // #6838/#6726 avoid hang on garbage code + if (!visitedParents.insert(tok->_astParent).second) // #6838/#6726 avoid hang on garbage code throw InternalError(this, "Internal error. Token::astOperand2() cyclic dependency."); tok = tok->_astParent; } diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index ed809834c..ba993ed4a 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -1253,6 +1253,12 @@ private: "b[i + 3] = a[i] * {}"), InternalError); // Don't hang (#5787) checkCode("START_SECTION([EXTRA](bool isValid(const String &filename)))"); // Don't crash (#5991) + + // #8352 + ASSERT_THROW(checkCode("else return % name5 name2 - =name1 return enum | { - name3 1 enum != >= 1 >= ++ { { || " + "{ return return { | { - name3 1 enum != >= 1 >= ++ { name6 | ; ++}}}}}}}"), InternalError); + ASSERT_THROW(checkCode("else return % name5 name2 - =name1 return enum | { - name3 1 enum != >= 1 >= ++ { { || " + "{ return return { | { - name3 1 enum != >= 1 >= ++ { { || ; ++}}}}}}}}"), InternalError); } void templateSimplifierCrashes() {