diff options
| author | 2024-12-28 15:00:29 +0100 | |
|---|---|---|
| committer | 2024-12-29 14:46:30 +0100 | |
| commit | 5c508b351a95f416e4a599f76902b888369de1b4 (patch) | |
| tree | e3f6363fd7458fb0a46eabde6bd3a65b4746d798 /src/libparser/node | |
| parent | 5515cd5a22ab97843f6ca1c234333ec110a9bab1 (diff) | |
| download | OneRoll-5c508b351a95f416e4a599f76902b888369de1b4.tar.gz OneRoll-5c508b351a95f416e4a599f76902b888369de1b4.zip | |
Several fix from fuzzer test.
Diffstat (limited to 'src/libparser/node')
| -rw-r--r-- | src/libparser/node/bind.cpp | 37 | ||||
| -rw-r--r-- | src/libparser/node/executionnode.cpp | 19 | ||||
| -rw-r--r-- | src/libparser/node/executionnode.h | 5 | ||||
| -rw-r--r-- | src/libparser/node/jumpbackwardnode.cpp | 9 | ||||
| -rw-r--r-- | src/libparser/node/jumpbackwardnode.h | 1 | ||||
| -rw-r--r-- | src/libparser/node/mergenode.cpp | 98 | ||||
| -rw-r--r-- | src/libparser/node/mergenode.h | 6 | ||||
| -rw-r--r-- | src/libparser/node/rerolldicenode.cpp | 61 |
8 files changed, 137 insertions, 99 deletions
diff --git a/src/libparser/node/bind.cpp b/src/libparser/node/bind.cpp index 41449d8..9c502df 100644 --- a/src/libparser/node/bind.cpp +++ b/src/libparser/node/bind.cpp @@ -38,27 +38,36 @@ void BindNode::run(ExecutionNode* previous) for(auto start : *m_startList) { ExecutionNode* last= getLatestNode(start); - if(nullptr != last) + if(!last) + continue; + + auto tmpResult= last->getResult(); + QSet<Result*> alreadyVisited; + while(nullptr != tmpResult && !alreadyVisited.contains(tmpResult)) { - auto tmpResult= last->getResult(); - while(nullptr != tmpResult) + alreadyVisited.insert(tmpResult); + DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult); + + if(nullptr != dice) { - DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult); - if(nullptr != dice) + m_diceResult->setHomogeneous(false); + auto list= dice->getResultList(); + for(int i= 0; i < list.size(); ++i) { - m_diceResult->setHomogeneous(false); - for(auto& die : dice->getResultList()) + auto die= list[i]; + + if(!die) + continue; + + if(!die->hasBeenDisplayed()) { - if(!die->hasBeenDisplayed()) - { - Die* tmpdie= new Die(*die); - die->displayed(); - m_diceResult->getResultList().append(tmpdie); - } + Die* tmpdie= new Die(*die); + die->displayed(); + m_diceResult->getResultList().append(tmpdie); } } - tmpResult= tmpResult->getPrevious(); } + tmpResult= tmpResult->getPrevious(); } } } diff --git a/src/libparser/node/executionnode.cpp b/src/libparser/node/executionnode.cpp index 096c8fe..b231416 100644 --- a/src/libparser/node/executionnode.cpp +++ b/src/libparser/node/executionnode.cpp @@ -2,6 +2,16 @@ #include <QUuid> +namespace +{ +#ifdef QT_DEBUG +constexpr int WaitingTime{2 * 1000 * 60}; +#else +constexpr int WaitingTime{30 * 60 * 1000}; +#endif + +} // namespace + ExecutionNode::ExecutionNode() : m_previousNode(nullptr) , m_result(nullptr) @@ -43,12 +53,19 @@ ExecutionNode* ExecutionNode::getNextNode() void ExecutionNode::execute(ExecutionNode* previous) { + QElapsedTimer timer; + timer.start(); + auto errorCount= m_errors.count(); run(previous); - if(m_nextNode && errorCount == m_errors.count()) + auto timeLimit= timer.hasExpired(WaitingTime); + + if(m_nextNode && errorCount == m_errors.count() && !timeLimit) m_nextNode->execute(this); + else if(timeLimit) + qDebug() << "Error too long" << WaitingTime << timeLimit << timer.elapsed(); } QMap<Dice::ERROR_CODE, QString> ExecutionNode::getExecutionErrorMap() diff --git a/src/libparser/node/executionnode.h b/src/libparser/node/executionnode.h index 342ae36..a2912e3 100644 --- a/src/libparser/node/executionnode.h +++ b/src/libparser/node/executionnode.h @@ -6,6 +6,7 @@ #include <diceparser/diceparserhelper.h> #include <QCoreApplication> +#include <QElapsedTimer> /** * @brief The ExecutionNode class */ @@ -87,7 +88,7 @@ public: protected: /** - * @brief m_nextNode + * @brief previous */ ExecutionNode* m_previousNode= nullptr; /** @@ -102,9 +103,7 @@ protected: * @brief m_errors */ QMap<Dice::ERROR_CODE, QString> m_errors; - QMap<Dice::ERROR_CODE, QString> m_warnings; - QString m_id; }; diff --git a/src/libparser/node/jumpbackwardnode.cpp b/src/libparser/node/jumpbackwardnode.cpp index e4ae59a..3e2f4c1 100644 --- a/src/libparser/node/jumpbackwardnode.cpp +++ b/src/libparser/node/jumpbackwardnode.cpp @@ -29,6 +29,11 @@ JumpBackwardNode::JumpBackwardNode() m_result= m_diceResult; } +JumpBackwardNode::~JumpBackwardNode() +{ + delete m_diceResult; +} + qint64 JumpBackwardNode::getPriority() const { return 4; @@ -126,13 +131,13 @@ void JumpBackwardNode::run(ExecutionNode* previous) for(auto& die : diceResult->getResultList()) { Die* tmpdie= new Die(*die); - //*tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } } - m_result->setPrevious(previous->getResult()); + if(m_result && previous) + m_result->setPrevious(previous->getResult()); if(m_nextNode) m_nextNode->execute(this); diff --git a/src/libparser/node/jumpbackwardnode.h b/src/libparser/node/jumpbackwardnode.h index 5f20291..2e14a00 100644 --- a/src/libparser/node/jumpbackwardnode.h +++ b/src/libparser/node/jumpbackwardnode.h @@ -33,6 +33,7 @@ public: * @brief JumpBackwardNode allows to get result from remote node in the execution tree. */ JumpBackwardNode(); + virtual ~JumpBackwardNode(); /** * @brief run - performs the actions * @param previous diff --git a/src/libparser/node/mergenode.cpp b/src/libparser/node/mergenode.cpp index 4c19bd7..8f30289 100644 --- a/src/libparser/node/mergenode.cpp +++ b/src/libparser/node/mergenode.cpp @@ -23,75 +23,82 @@ #include <diceparser/parsingtoolbox.h> -MergeNode::MergeNode() : m_diceResult(new DiceResult()) +MergeNode::MergeNode(std::vector<ExecutionNode*>& startList) : m_startList(startList), m_diceResult(new DiceResult()) { m_result= m_diceResult; } + +int findDistance(const std::vector<ExecutionNode*>& startList, MergeNode* node) +{ + int i= 0; + for(auto start : startList) + { + auto temp= start; + while(temp != nullptr) + { + if(temp == node) + return i; + temp= temp->getNextNode(); + } + ++i; + } + return i; +} void MergeNode::run(ExecutionNode* previous) { if(isValid(!previous, Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No previous node before Merge operator"))) return; - m_previousNode= previous; - m_result->setPrevious(previous->getResult()); - ExecutionNode* previousLast= nullptr; - std::vector<Result*> pastResult; - if(!m_startList) + // m_previousNode= previous; + // m_result->setPrevious(previous->getResult()); + // std::vector<Result*> pastResult; + if(isValid(m_startList.empty(), Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No several instruction"))) return; - for(auto start : *m_startList) - { - ExecutionNode* last= getLatestNode(start); - if(nullptr == last || nullptr == previousLast) - { - previousLast= last; - continue; - } - - auto startResult= start->getResult(); - if(nullptr == startResult) - continue; + auto instId= findDistance(m_startList, this); - startResult->setPrevious(previousLast->getResult()); - previousLast->setNextNode(start); + ExecutionNode* previousLast= nullptr; + std::for_each(std::begin(m_startList), std::end(m_startList), + [&previousLast, this](ExecutionNode* node) + { + ExecutionNode* last= getLatestNode(node); + if(previousLast) + { + previousLast->setNextNode(node); + auto resultNode= node->getResult(); + if(resultNode) + resultNode->setPrevious(previousLast->getResult()); + } + previousLast= last; + }); - previousLast= last; - Result* tmpResult= last->getResult(); + if(instId != 0) + { + Result* tmpResult= previous->getResult(); while(nullptr != tmpResult) { DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult); - if(nullptr != dice) + if(nullptr != dice && dice != m_diceResult) { - ///@todo TODO improve here to set homogeneous while is really m_diceResult->setHomogeneous(false); + for(auto& die : dice->getResultList()) { if(!m_diceResult->getResultList().contains(die) && (!die->hasBeenDisplayed())) { Die* tmpdie= new Die(*die); die->displayed(); - m_diceResult->getResultList().append(tmpdie); + m_diceResult->insertResult(tmpdie); } } } - auto it= std::find_if(pastResult.begin(), pastResult.end(), - [tmpResult](const Result* a) { return (a == tmpResult->getPrevious()); }); - if(it == pastResult.end()) - { - pastResult.push_back(previousLast->getResult()); - tmpResult= tmpResult->getPrevious(); - } - else - { - tmpResult->setPrevious(nullptr); - tmpResult= nullptr; - } + tmpResult= tmpResult->getPrevious(); } } - auto first= m_startList->front(); - m_startList->clear(); - m_startList->push_back(first); + auto first= m_startList.front(); + m_startList.clear(); + m_startList.push_back(first); } #include <QDebug> ExecutionNode* MergeNode::getLatestNode(ExecutionNode* node) @@ -126,7 +133,7 @@ qint64 MergeNode::getPriority() const } ExecutionNode* MergeNode::getCopy() const { - MergeNode* node= new MergeNode(); + MergeNode* node= new MergeNode(m_startList); if(nullptr != m_nextNode) { node->setNextNode(m_nextNode->getCopy()); @@ -134,12 +141,7 @@ ExecutionNode* MergeNode::getCopy() const return node; } -std::vector<ExecutionNode*>* MergeNode::getStartList() const -{ - return m_startList; -} - -void MergeNode::setStartList(std::vector<ExecutionNode*>* startList) +/*void MergeNode::setStartList(const std::vector<ExecutionNode*>& startList) { m_startList= startList; -} +}*/ diff --git a/src/libparser/node/mergenode.h b/src/libparser/node/mergenode.h index 515a2e9..1b32352 100644 --- a/src/libparser/node/mergenode.h +++ b/src/libparser/node/mergenode.h @@ -31,20 +31,18 @@ class MergeNode : public ExecutionNode { public: - MergeNode(); + MergeNode(std::vector<ExecutionNode*>& startList); void run(ExecutionNode* previous); virtual QString toString(bool withLabel) const; virtual qint64 getPriority() const; virtual ExecutionNode* getCopy() const; - std::vector<ExecutionNode*>* getStartList() const; - void setStartList(std::vector<ExecutionNode*>* startList); private: ExecutionNode* getLatestNode(ExecutionNode* node); private: + std::vector<ExecutionNode*>& m_startList; DiceResult* m_diceResult= nullptr; - std::vector<ExecutionNode*>* m_startList= nullptr; }; #endif // NUMBERNODE_H diff --git a/src/libparser/node/rerolldicenode.cpp b/src/libparser/node/rerolldicenode.cpp index af075ce..25143ac 100644 --- a/src/libparser/node/rerolldicenode.cpp +++ b/src/libparser/node/rerolldicenode.cpp @@ -19,74 +19,81 @@ RerollDiceNode::~RerollDiceNode() } void RerollDiceNode::run(ExecutionNode* previous) { - if(isValid(!previous, Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No Previous node"))) + using DE= Dice::ERROR_CODE; + using DC= Dice::CONDITION_STATE; + if(isValid(!previous, DE::NO_PREVIOUS_ERROR, tr("No Previous node"))) return; m_previousNode= previous; auto previousDiceResult= previous->getResult(); - if(isValid(!previousDiceResult, Dice::ERROR_CODE::NO_VALID_RESULT, tr("No Valid result"))) + if(isValid(!previousDiceResult, DE::NO_VALID_RESULT, tr("No Valid result"))) return; DiceResult* previous_result= dynamic_cast<DiceResult*>(previousDiceResult); - if(isValid(!previous_result, Dice::ERROR_CODE::DIE_RESULT_EXPECTED, + if(isValid(!previous_result, DE::DIE_RESULT_EXPECTED, tr(" The a operator expects dice result. Please check the documentation and fix your command."))) return; m_result->setPrevious(previous_result); - for(auto& die : previous_result->getResultList()) + for(auto const& die : previous_result->getResultList()) { + if(!die) + return; + Die* tmpdie= new Die(*die); m_diceResult->insertResult(tmpdie); die->displayed(); } - // m_diceResult->setResultList(list); QList<Die*>& list= m_diceResult->getResultList(); QList<Die*> toRemove; - for(auto& die : list) + for(int i= 0; i < list.size(); ++i) { + auto die= list[i]; + if(!die) + continue; + bool finished= false; auto state = m_validatorList->isValidRangeSize(std::make_pair<qint64, qint64>(die->getBase(), die->getMaxValue())); - if((Dice::CONDITION_STATE::ALWAYSTRUE == state && m_adding) - || (!m_reroll && !m_adding && state == Dice::CONDITION_STATE::UNREACHABLE)) + + if(isValid((DC::ALWAYSTRUE == state && m_adding) || (!m_reroll && !m_adding && state == DC::UNREACHABLE), + DE::ENDLESS_LOOP_ERROR, + QStringLiteral("Condition cause an endless loop with this dice: %1") + .arg(QStringLiteral("d[%1,%2]") + .arg(static_cast<int>(die->getBase())) + .arg(static_cast<int>(die->getMaxValue()))))) { - m_errors.insert(Dice::ERROR_CODE::ENDLESS_LOOP_ERROR, - QObject::tr("Condition (%1) cause an endless loop with this dice: %2") - .arg(toString(true)) - .arg(QStringLiteral("d[%1,%2]") - .arg(static_cast<int>(die->getBase())) - .arg(static_cast<int>(die->getMaxValue())))); continue; } + while(m_validatorList->hasValid(die, false) && !finished) { - if(m_instruction != nullptr) + if(m_instruction) { m_instruction->execute(this); auto lastNode= ParsingToolBox::getLeafNode(m_instruction); - if(lastNode != nullptr) + if(lastNode == nullptr) + continue; + auto lastResult= dynamic_cast<DiceResult*>(lastNode->getResult()); + if(lastResult != nullptr) { - auto lastResult= dynamic_cast<DiceResult*>(lastNode->getResult()); - if(lastResult != nullptr) - { - toRemove.append(die); - list.append(lastResult->getResultList()); - lastResult->clear(); - } + toRemove.append(die); + if(list.size() < lastResult->getResultList().size()) + break; + list.append(lastResult->getResultList()); + die= list[i]; + lastResult->clear(); } } else { die->roll(m_adding); } - if(m_reroll) - { - finished= true; - } + finished= m_reroll; } } |