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 --- parsingtoolbox.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'parsingtoolbox.cpp') 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 'parsingtoolbox.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 a817fcbaa3350a59790d9b264d8eb613df80703d Mon Sep 17 00:00:00 2001 From: Renaud G Date: Sun, 28 Jul 2019 01:41:34 +0200 Subject: Add bool return to manage no parameter on painter node --- include/parsingtoolbox.h | 2 +- parsingtoolbox.cpp | 38 +++++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'parsingtoolbox.cpp') diff --git a/include/parsingtoolbox.h b/include/parsingtoolbox.h index 9e246d6..8d5f62b 100644 --- a/include/parsingtoolbox.h +++ b/include/parsingtoolbox.h @@ -206,7 +206,7 @@ public: bool readArithmeticOperator(QString& str, Die::ArithmeticOperator& op); - static void readPainterParameter(PainterNode* painter, QString& str); + static bool readPainterParameter(PainterNode* painter, QString& str); static QHash getVariableHash(); static void setVariableHash(const QHash& variableHash); diff --git a/parsingtoolbox.cpp b/parsingtoolbox.cpp index 4084825..7caeefe 100644 --- a/parsingtoolbox.cpp +++ b/parsingtoolbox.cpp @@ -661,28 +661,32 @@ ParsingToolBox::LIST_OPERATOR ParsingToolBox::readListOperator(QString& str) return NONE; } -void ParsingToolBox::readPainterParameter(PainterNode* painter, QString& str) +bool ParsingToolBox::readPainterParameter(PainterNode* painter, QString& str) { - if(str.startsWith('[')) - { - str= str.remove(0, 1); - int pos= str.indexOf(']'); + if(!str.startsWith('[')) + return false; + + str= str.remove(0, 1); + int pos= str.indexOf(']'); - if(pos > -1) + if(pos == -1) + return false; + + QString data= str.left(pos); + str= str.remove(0, pos + 1); + QStringList duos= data.split(','); + bool result= false; + for(QString& duoStr : duos) + { + QStringList keyValu= duoStr.split(':'); + if(keyValu.size() == 2) { - QString data= str.left(pos); - str= str.remove(0, pos + 1); - QStringList duos= data.split(','); - for(QString& duoStr : duos) - { - QStringList keyValu= duoStr.split(':'); - if(keyValu.size() == 2) - { - painter->insertColorItem(keyValu[1], keyValu[0].toInt()); - } - } + painter->insertColorItem(keyValu[1], keyValu[0].toInt()); + result= true; } } + + return result; } QHash ParsingToolBox::getVariableHash() -- cgit v1.2.3-70-g09d2 From b720a51745b5473cd9054cb0ed7493017ace23b1 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Sun, 28 Jul 2019 02:39:54 +0200 Subject: remove use of pointer --- parsingtoolbox.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'parsingtoolbox.cpp') diff --git a/parsingtoolbox.cpp b/parsingtoolbox.cpp index 7caeefe..4372b41 100644 --- a/parsingtoolbox.cpp +++ b/parsingtoolbox.cpp @@ -281,16 +281,16 @@ Validator* ParsingToolBox::readCompositeValidator(QString& str) Validator* tmp= readValidator(str, expectSquareBrasket); CompositeValidator::LogicOperation opLogic; - QVector* operators= new QVector(); - QList* validatorList= new QList(); + QVector operators; + QList validatorList; while(nullptr != tmp) { bool hasOperator= readLogicOperation(str, opLogic); if(hasOperator) { - operators->append(opLogic); - validatorList->append(tmp); + operators.append(opLogic); + validatorList.append(tmp); tmp= readValidator(str, expectSquareBrasket); } else @@ -301,19 +301,19 @@ Validator* ParsingToolBox::readCompositeValidator(QString& str) // isOk=true; } - if(!validatorList->isEmpty()) + if(!validatorList.isEmpty()) { - validatorList->append(tmp); + validatorList.append(tmp); } else { - delete operators; + operators.clear(); return tmp; } tmp= nullptr; } } - if(!validatorList->isEmpty()) + if(!validatorList.isEmpty()) { CompositeValidator* validator= new CompositeValidator(); validator->setOperationList(operators); @@ -322,7 +322,6 @@ Validator* ParsingToolBox::readCompositeValidator(QString& str) } else { - delete operators; return nullptr; } } -- cgit v1.2.3-70-g09d2