diff options
author | Adrian Kummerländer | 2013-10-19 14:49:03 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2013-10-19 14:49:03 +0200 |
commit | aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52 (patch) | |
tree | ebfde8ea3f2a7670a0fbc62fe81aac2c7662fc86 | |
parent | 041a56a919ae49db46fa34adc8de90f0feb69bb0 (diff) | |
download | SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.gz SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.bz2 SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.lz SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.xz SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.zst SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.zip |
Fixed undefined behavior of tree construction
* Invalid input syntax led to undefined behavior when accessing the top element of an empty stack
** Fixed by introducing a new "topNodeFrom" function which throws an exeption in the case that the given std::stack reference is empty
-rw-r--r-- | src/parser.h | 2 | ||||
-rw-r--r-- | src/tree.cc | 24 |
2 files changed, 17 insertions, 9 deletions
diff --git a/src/parser.h b/src/parser.h index 54e540a..89c0493 100644 --- a/src/parser.h +++ b/src/parser.h @@ -6,7 +6,7 @@ namespace SimpleParser { double calculate(std::string); -std::string exportTree(std::string); +std::string print(std::string); } diff --git a/src/tree.cc b/src/tree.cc index 45484c6..1dcfca6 100644 --- a/src/tree.cc +++ b/src/tree.cc @@ -96,6 +96,14 @@ Node* Tree::addOperator(Node** place, char oper) { return this->node_collection_.back().get(); } +Node* topNodeFrom(const std::stack<Node*>& stack) { + if ( !stack.empty() ) { + return stack.top(); + } else { + throw operator_exception(); + } +} + Node* Tree::buildTree(std::string term) { std::stack<Node*> operandStack; std::stack<Node*> operatorStack; @@ -114,7 +122,7 @@ Node* Tree::buildTree(std::string term) { if ( priority != -1 && (*termIter).size() == 1 ) { if ( !operatorStack.empty() ) { OperatorNode* lastNode( - static_cast<OperatorNode*>(operatorStack.top()) + static_cast<OperatorNode*>(topNodeFrom(operatorStack)) ); if ( getPriority(lastNode->getFunction()) < priority ) { @@ -122,13 +130,13 @@ Node* Tree::buildTree(std::string term) { this->addOperator(nullptr, currTerm[0]) ); } else { - Node* currOperator = operatorStack.top(); + Node* currOperator = topNodeFrom(operatorStack); operatorStack.pop(); - currOperator->rightChild = operandStack.top(); + currOperator->rightChild = topNodeFrom(operandStack); operandStack.pop(); - currOperator->leftChild = operandStack.top(); + currOperator->leftChild = topNodeFrom(operandStack); operandStack.pop(); operandStack.push(currOperator); @@ -161,20 +169,20 @@ Node* Tree::buildTree(std::string term) { while ( !operatorStack.empty() ) { OperatorNode *currOperator( - static_cast<OperatorNode*>(operatorStack.top()) + static_cast<OperatorNode*>(topNodeFrom(operatorStack)) ); operatorStack.pop(); - currOperator->rightChild = operandStack.top(); + currOperator->rightChild = topNodeFrom(operandStack); operandStack.pop(); - currOperator->leftChild = operandStack.top(); + currOperator->leftChild = topNodeFrom(operandStack); operandStack.pop(); operandStack.push(currOperator); } - return operandStack.top(); + return topNodeFrom(operandStack); } } |