Add maximum call stack size in batch mode 61/170261/9
authorLukasz Wlazly <l.wlazly@partner.samsung.com>
Fri, 16 Feb 2018 10:07:29 +0000 (11:07 +0100)
committerRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Tue, 28 May 2019 09:43:53 +0000 (11:43 +0200)
Change-Id: I2d86c00fec929dbbfbe82d58297101be583f1834

src/batch/EvaluationContext.cpp
src/batch/EvaluationContext.hpp
tests/no-ui-scenarios/BatchExecTests.cpp

index d9b4b9d..aa4b588 100644 (file)
@@ -28,13 +28,13 @@ EvaluationContext &EvaluationContext::getCurrentEvaluationContext()
        return *current;
 }
 
-EvaluationContext::EvaluationContext(ExecutorInterface &ei) : parent(current)
+EvaluationContext::EvaluationContext(ExecutorInterface &ei) : parent(current), stackLevel(initializeStackLevel(parent))
 {
        current = this;
        initializeGlobalContext(ei);
 }
 
-EvaluationContext::EvaluationContext() : parent(current)
+EvaluationContext::EvaluationContext() : parent(current), stackLevel(initializeStackLevel(parent))
 {
        ASSERT(parent);
        current = this;
@@ -42,7 +42,7 @@ EvaluationContext::EvaluationContext() : parent(current)
        this->data->parent = parent->data;
 }
 
-EvaluationContext::EvaluationContext(std::shared_ptr<Data> data) : parent(current)
+EvaluationContext::EvaluationContext(std::shared_ptr<Data> data) : parent(current), stackLevel(initializeStackLevel(parent))
 {
        current = this;
        globalContext = this->parent->globalContext;
@@ -124,6 +124,22 @@ Rectangle ExecutorInterface::getUIElementPosition(const std::shared_ptr<UIElemen
        throw EvaluationFailure{} << "getUIElementPosition not implemeneted";
 }
 
+size_t EvaluationContext::getStackLevel() const
+{
+       return stackLevel;
+}
+
+size_t EvaluationContext::initializeStackLevel(EvaluationContext *parent)
+{
+       if (!parent)
+               return 0;
+
+       if (parent->getStackLevel() >= MAX_CALL_STACK_LEVEL)
+               throw EvaluationFailure{} << "Maximum call stack size exceeded";
+
+       return parent->getStackLevel() + 1;
+}
+
 std::string ExecutorInterface::getUIElementName(const std::shared_ptr<UIElement> &elem)
 {
        throw EvaluationFailure{} << "getUIElementName not implemeneted";
index be0e828..b49f9be 100644 (file)
@@ -199,13 +199,19 @@ public:
         */
        const std::string &topBatchPath();
 
+       size_t getStackLevel() const;
+
 private:
        void initializeGlobalContext(ExecutorInterface &ei);
+       static size_t initializeStackLevel(EvaluationContext *parent);
 
        std::shared_ptr<Data> data = std::make_shared<Data>();
        EvaluationContext *parent = nullptr;
        std::shared_ptr<GlobalContext> globalContext;
        std::vector<const std::string *> batchPathStack;
+       const size_t stackLevel = 0;
+
+       static constexpr size_t MAX_CALL_STACK_LEVEL = 64;
 };
 
 #endif
index b49928d..7f667d1 100644 (file)
@@ -1046,6 +1046,19 @@ TEST_F(ScriptTest, functionReturn)
        ASSERT_EQ(expected, 13);
 }
 
+TEST_F(ScriptTest, functionRecursiveCall)
+{
+       TestBatchExecutor exec;
+       EvaluationContext ec{ exec };
+
+       ASSERT_THROW(
+               execute("def myFunc() {\n"
+                               "   myFunc()\n"
+                               " }\n"
+                               "myFunc()", ec, false)
+               , EvaluationFailure);
+}
+
 int main(int argc, char *argv[])
 {
        try {