From bb6b87a2685c0d71b5c38be33c100f85ac0b9cee Mon Sep 17 00:00:00 2001 From: Renaud G Date: Thu, 25 Jul 2019 09:59:29 +0200 Subject: Rework of the component to be a proper lib --- operationcondition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'operationcondition.cpp') diff --git a/operationcondition.cpp b/operationcondition.cpp index 53a994d..67b10fc 100644 --- a/operationcondition.cpp +++ b/operationcondition.cpp @@ -131,5 +131,5 @@ qint64 OperationCondition::valueToScalar() const m_value->run(nullptr); auto result= m_value->getResult(); - return result->getResult(Result::SCALAR).toInt(); + return result->getResult(Dice::RESULT_TYPE::SCALAR).toInt(); } -- cgit v1.2.3-70-g09d2 From 8b04d886845be5c3b57caae4d96b53133c51ab14 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Thu, 25 Jul 2019 22:29:20 +0200 Subject: Fix crash found by afl --- booleancondition.cpp | 5 ++++- node/scalaroperatornode.cpp | 7 +++++++ operationcondition.cpp | 4 ++++ parsingtoolbox.cpp | 8 ++++++-- 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'operationcondition.cpp') diff --git a/booleancondition.cpp b/booleancondition.cpp index c81f5ab..6747727 100644 --- a/booleancondition.cpp +++ b/booleancondition.cpp @@ -159,5 +159,8 @@ qint64 BooleanCondition::valueToScalar() const m_value->run(nullptr); auto result= m_value->getResult(); - return result->getResult(Dice::RESULT_TYPE::SCALAR).toInt(); + if(result) + return result->getResult(Dice::RESULT_TYPE::SCALAR).toInt(); + else + return 0; } diff --git a/node/scalaroperatornode.cpp b/node/scalaroperatornode.cpp index 9edbcdc..821150b 100644 --- a/node/scalaroperatornode.cpp +++ b/node/scalaroperatornode.cpp @@ -66,6 +66,13 @@ void ScalarOperatorNode::run(ExecutionNode* previous) m_internalNode->getResult()->setPrevious(previousResult); } + if(internalResult == nullptr) + { + m_errors.insert(Dice::ERROR_CODE::NO_VALID_RESULT, + QObject::tr("No Valid result in arithmetic operatoion: %1").arg(toString(true))); + return; + } + switch(m_arithmeticOperator) { case Die::PLUS: diff --git a/operationcondition.cpp b/operationcondition.cpp index 67b10fc..507416d 100644 --- a/operationcondition.cpp +++ b/operationcondition.cpp @@ -41,6 +41,10 @@ void OperationCondition::setBoolean(BooleanCondition* boolean) qint64 OperationCondition::hasValid(Die* b, bool recursive, bool unhighlight) const { + if(nullptr == m_boolean) + { + return 0; + } QList listValues; if(recursive) { diff --git a/parsingtoolbox.cpp b/parsingtoolbox.cpp index 702019d..2453eb7 100644 --- a/parsingtoolbox.cpp +++ b/parsingtoolbox.cpp @@ -204,13 +204,17 @@ Validator* ParsingToolBox::readValidator(QString& str, bool hasSquare) { OperationCondition* condition= new OperationCondition(); condition->setValueNode(operandNode); - Validator* valid= readValidator(str,hasSquare); + Validator* valid= readValidator(str, hasSquare); BooleanCondition* boolC= dynamic_cast(valid); if(nullptr != boolC) { condition->setBoolean(boolC); + returnVal= condition; + } + else + { + delete condition; } - returnVal= condition; } } else if(readOperand(str, operandNode)) -- cgit v1.2.3-70-g09d2 From 7f535260bbc2210bf8d605bac88546e9f18b2b05 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Sun, 28 Jul 2019 01:35:59 +0200 Subject: New API for isValidRangeSize --- include/diceparserhelper.h | 8 ++++++++ include/parsingtoolbox.h | 2 +- node/explodedicenode.cpp | 14 ++++++++++++-- operationcondition.cpp | 21 ++++++++++++++------- operationcondition.h | 2 +- parsingtoolbox.cpp | 16 +++++----------- range.cpp | 16 ++++++++++++---- range.h | 1 + 8 files changed, 54 insertions(+), 26 deletions(-) (limited to 'operationcondition.cpp') diff --git a/include/diceparserhelper.h b/include/diceparserhelper.h index 5013ebe..00b9362 100644 --- a/include/diceparserhelper.h +++ b/include/diceparserhelper.h @@ -4,6 +4,14 @@ namespace Dice { +enum class CONDITION_STATE : int +{ + ERROR, + ALWAYSTRUE, + UNREACHABLE, + REACHABLE +}; + enum class ERROR_CODE : int { NO_DICE_ERROR, diff --git a/include/parsingtoolbox.h b/include/parsingtoolbox.h index b91db1a..9e246d6 100644 --- a/include/parsingtoolbox.h +++ b/include/parsingtoolbox.h @@ -175,7 +175,7 @@ public: * @param val * @return */ - bool isValidValidator(ExecutionNode* previous, Validator* val); + Dice::CONDITION_STATE isValidValidator(ExecutionNode* previous, Validator* val); /** * @brief getDiceRollerNode * @param previous diff --git a/node/explodedicenode.cpp b/node/explodedicenode.cpp index 704ac8a..2292a05 100644 --- a/node/explodedicenode.cpp +++ b/node/explodedicenode.cpp @@ -16,7 +16,6 @@ void ExplodeDiceNode::run(ExecutionNode* previous) for(auto& die : previous_result->getResultList()) { Die* tmpdie= new Die(*die); -// *tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } @@ -25,12 +24,23 @@ void ExplodeDiceNode::run(ExecutionNode* previous) for(auto& die : list) { + if(Dice::CONDITION_STATE::ALWAYSTRUE + == m_validator->isValidRangeSize(std::make_pair(die->getBase(), 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(die->getBase())) + .arg(static_cast(die->getMaxValue())))); + continue; + } + while(m_validator->hasValid(die, false)) { die->roll(true); } } - // m_diceResult->setResultList(list); if(nullptr != m_nextNode) { diff --git a/operationcondition.cpp b/operationcondition.cpp index 507416d..97c7bce 100644 --- a/operationcondition.cpp +++ b/operationcondition.cpp @@ -106,15 +106,22 @@ QString OperationCondition::toString() } return QStringLiteral("[%1%2%3]").arg(str).arg(valueToScalar()).arg(m_boolean->toString()); } -bool OperationCondition::isValidRangeSize(std::pair) const +Dice::CONDITION_STATE OperationCondition::isValidRangeSize(const std::pair& range) const { - auto value= valueToScalar(); - bool valid= true; + Dice::CONDITION_STATE valid= Dice::CONDITION_STATE::REACHABLE; - if(value == 0) - valid= false; - /* else if(nullptr != m_boolean) - valid = m_boolean->isValidRangeSize(range);*/ + auto rangeIsClose= (range.first == range.second); + + Die die; + die.insertRollValue(range.first); + + if(nullptr == m_boolean) + return Dice::CONDITION_STATE::ERROR; + + if(rangeIsClose && m_boolean->hasValid(&die, false, false)) + valid= Dice::CONDITION_STATE::ALWAYSTRUE; + else if(rangeIsClose && !m_boolean->hasValid(&die, false, false)) + valid= Dice::CONDITION_STATE::UNREACHABLE; return valid; } diff --git a/operationcondition.h b/operationcondition.h index 86562e6..8b5a411 100644 --- a/operationcondition.h +++ b/operationcondition.h @@ -43,7 +43,7 @@ public: void setValueNode(ExecutionNode* node); QString toString(); - virtual bool isValidRangeSize(std::pair range) const; + virtual Dice::CONDITION_STATE isValidRangeSize(const std::pair& range) const override; BooleanCondition* getBoolean() const; void setBoolean(BooleanCondition* boolean); diff --git a/parsingtoolbox.cpp b/parsingtoolbox.cpp index 2453eb7..4084825 100644 --- a/parsingtoolbox.cpp +++ b/parsingtoolbox.cpp @@ -601,19 +601,13 @@ bool ParsingToolBox::readAscending(QString& str) } return false; } -bool ParsingToolBox::isValidValidator(ExecutionNode* previous, Validator* val) +Dice::CONDITION_STATE ParsingToolBox::isValidValidator(ExecutionNode* previous, Validator* val) { DiceRollerNode* node= getDiceRollerNode(previous); - bool valid= false; - if(nullptr != node) - { - valid= val->isValidRangeSize(node->getRange()); - } - else - { - valid= true; - } - return valid; + if(nullptr == node) + return Dice::CONDITION_STATE::ERROR; + + return val->isValidRangeSize(node->getRange()); } DiceRollerNode* ParsingToolBox::getDiceRollerNode(ExecutionNode* previous) { diff --git a/range.cpp b/range.cpp index 471784c..8eeff4e 100644 --- a/range.cpp +++ b/range.cpp @@ -58,12 +58,20 @@ QString Range::toString() { return QStringLiteral("[%1-%2]").arg(m_start).arg(m_end); } -bool Range::isValidRangeSize(std::pair range) const +Dice::CONDITION_STATE Range::isValidRangeSize(const std::pair& range) const { - auto newStart= qBound(range.first, m_start, range.second); - auto newEnd= qBound(range.first, m_end, range.second); + auto minRange= std::min(m_start, m_end); + auto minPossibleValue= std::min(range.first, range.second); - return (newStart == m_start && newEnd == m_end && m_end >= m_start); + auto maxRange= std::max(m_start, m_end); + auto maxPossibleValue= std::max(range.first, range.second); + + if(minRange == minPossibleValue && maxRange == maxPossibleValue) + return Dice::CONDITION_STATE::ALWAYSTRUE; + else if(maxRange < minPossibleValue || minRange > maxPossibleValue) + return Dice::CONDITION_STATE::UNREACHABLE; + else + return Dice::CONDITION_STATE::UNREACHABLE; } void Range::setStart(qint64 start) { diff --git a/range.h b/range.h index 17cc9ad..596d8f3 100644 --- a/range.h +++ b/range.h @@ -39,6 +39,7 @@ public: virtual QString toString(); virtual bool isValidRangeSize(std::pair range) const; + virtual Dice::CONDITION_STATE isValidRangeSize(const std::pair& range) const override; bool isFullyDefined() const; qint64 getStart() const; -- cgit v1.2.3-70-g09d2 From 58893c479bfdf2ea7631bff12710a436c3bcfa51 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Sun, 28 Jul 2019 02:38:00 +0200 Subject: set of possibility --- operationcondition.cpp | 20 +++++++++++++++++++- operationcondition.h | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'operationcondition.cpp') diff --git a/operationcondition.cpp b/operationcondition.cpp index 97c7bce..9ef8e1e 100644 --- a/operationcondition.cpp +++ b/operationcondition.cpp @@ -68,7 +68,7 @@ qint64 OperationCondition::hasValid(Die* b, bool recursive, bool unhighlight) co if(valueScalar == 0) valueScalar= 1; die.insertRollValue(value % valueScalar); - sum+= m_boolean->hasValid(&die, recursive, false); + sum+= m_boolean->hasValid(&die, recursive, false) ? 1 : 0; } break; } @@ -125,6 +125,7 @@ Dice::CONDITION_STATE OperationCondition::isValidRangeSize(const std::pairgetResult(); return result->getResult(Dice::RESULT_TYPE::SCALAR).toInt(); } + +const std::set& OperationCondition::getPossibleValues(const std::pair& range) +{ + if(nullptr == m_boolean) + return m_values; + + for(qint64 i= std::min(range.first, range.second); i <= std::max(range.first, range.second); ++i) + { + auto valueScalar= valueToScalar(); + auto val= i % valueScalar; + Die die; + die.insertRollValue(val); + if(m_boolean->hasValid(&die, false, false)) + m_values.insert(i); + } + return m_values; +} diff --git a/operationcondition.h b/operationcondition.h index b324f6b..423148d 100644 --- a/operationcondition.h +++ b/operationcondition.h @@ -49,6 +49,7 @@ public: void setBoolean(BooleanCondition* boolean); virtual Validator* getCopy() const; + const std::set& getPossibleValues(const std::pair& range) override; private: qint64 valueToScalar() const; -- cgit v1.2.3-70-g09d2