]> granicus.if.org Git - icinga2/commitdiff
Fix parser error when using new-lines in dictionaries
authorGunnar Beutner <gunnar@beutner.name>
Wed, 23 Sep 2015 14:37:21 +0000 (16:37 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Tue, 13 Oct 2015 11:01:50 +0000 (13:01 +0200)
fixes #10204

lib/config/config_lexer.ll
lib/config/config_parser.yy
lib/config/configcompiler.cpp
lib/config/configcompiler.hpp
test/config-ops.cpp

index abe0a34c66bfcef842b9988fee8da7fe31576f7e..372dfc6d368348006af654697e7e64070953c257 100644 (file)
@@ -252,9 +252,9 @@ in                          return T_IN;
 \>                             return T_GREATER_THAN;
 }
 
-\(                             { yyextra->m_IgnoreNewlines++; return '('; }
-\)                             { yyextra->m_IgnoreNewlines--; return ')'; }
-[\r\n]+                                { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines) { return T_NEWLINE; } }
+\(                             { yyextra->m_IgnoreNewlines.push(true); return '('; }
+\)                             { yyextra->m_IgnoreNewlines.pop(); return ')'; }
+[\r\n]+                                { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines.top()) { return T_NEWLINE; } }
 <<EOF>>                                { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } }
 .                              return yytext[0];
 
index fd4e1995a307d4dcc5642884e89df392eec9228d..54e1c6dc8672f1549b53711f1d51fe23c8f9341e 100644 (file)
@@ -258,9 +258,13 @@ Expression *ConfigCompiler::Compile(void)
 
        //yydebug = 1;
 
+       m_IgnoreNewlines.push(false);
+
        if (yyparse(&llist, this) != 0)
                return NULL;
 
+       m_IgnoreNewlines.pop();
+
        std::vector<Expression *> dlist;
        typedef std::pair<Expression *, EItemInfo> EListItem;
        int num = 0;
@@ -733,11 +737,13 @@ rterm_array: '['
 
 rterm_scope_require_side_effect: '{'
        {
+               context->m_IgnoreNewlines.push(false);
                context->m_OpenBraces++;
        }
        statements '}'
        {
                context->m_OpenBraces--;
+               context->m_IgnoreNewlines.pop();
                std::vector<Expression *> dlist;
                typedef std::pair<Expression *, EItemInfo> EListItem;
                int num = 0;
@@ -754,11 +760,13 @@ rterm_scope_require_side_effect: '{'
 
 rterm_scope: '{'
        {
+               context->m_IgnoreNewlines.push(false);
                context->m_OpenBraces++;
        }
        statements '}'
        {
                context->m_OpenBraces--;
+               context->m_IgnoreNewlines.pop();
                std::vector<Expression *> dlist;
                typedef std::pair<Expression *, EItemInfo> EListItem;
                int num = 0;
index 6d7edccf24ee23c063c61e28ae5fa45b419944b2..f0cca61c26e322053af8290e0f58bea7c5479462 100644 (file)
@@ -39,7 +39,7 @@ std::vector<String> ConfigCompiler::m_IncludeSearchDirs;
  * @param zone The zone.
  */
 ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone)
-       : m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false), m_OpenBraces(0), m_IgnoreNewlines(0)
+       : m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false), m_OpenBraces(0)
 {
        InitializeScanner();
 }
index aa438473e874a7811154e8968de64c30d41a71a4..47a6299b928532ae5c627ece28d7a6cc1e22f2a7 100644 (file)
@@ -120,13 +120,13 @@ public:
        bool m_Eof;
        int m_OpenBraces;
 
-       int m_IgnoreNewlines;
        std::ostringstream m_LexBuffer;
        CompilerDebugInfo m_LocationBegin;
 
        std::stack<TypeRuleList::Ptr> m_RuleLists;
        ConfigType::Ptr m_Type;
 
+       std::stack<bool> m_IgnoreNewlines;
        std::stack<bool> m_Apply;
        std::stack<bool> m_ObjectAssign;
        std::stack<bool> m_SeenAssign;
index 6468e31774f8308c8daa11cb381a173a33a5d0cd..c34a901e0a01ac5b6f136323da645b9b288de30f 100644 (file)
@@ -203,6 +203,10 @@ BOOST_AUTO_TEST_CASE(simple)
        expr = ConfigCompiler::CompileText("<test>", "\"\\'test\"");
        BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
        delete expr;
+
+       expr = ConfigCompiler::CompileText("<test>", "({ a = 3\nb = 3 })");
+       BOOST_CHECK(expr->Evaluate(frame).GetValue().IsObjectType<Dictionary>());
+       delete expr;
 }
 
 BOOST_AUTO_TEST_CASE(advanced)