From: Gunnar Beutner Date: Wed, 23 Sep 2015 14:37:21 +0000 (+0200) Subject: Fix parser error when using new-lines in dictionaries X-Git-Tag: v2.4.0~291 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e19a36c6593a5d7f9a52cf9055234c565872fa39;p=icinga2 Fix parser error when using new-lines in dictionaries fixes #10204 --- diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index f03ea8e83..94d99e438 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -240,9 +240,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; } } <> { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } } . return yytext[0]; diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 120a89f82..07d014a71 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -240,9 +240,13 @@ Expression *ConfigCompiler::Compile(void) //yydebug = 1; + m_IgnoreNewlines.push(false); + if (yyparse(&llist, this) != 0) return NULL; + m_IgnoreNewlines.pop(); + std::vector dlist; typedef std::pair EListItem; int num = 0; @@ -612,11 +616,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 dlist; typedef std::pair EListItem; int num = 0; @@ -633,11 +639,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 dlist; typedef std::pair EListItem; int num = 0; diff --git a/lib/config/configcompiler.cpp b/lib/config/configcompiler.cpp index 0be38a9cc..de91cb883 100644 --- a/lib/config/configcompiler.cpp +++ b/lib/config/configcompiler.cpp @@ -44,7 +44,7 @@ std::map > ConfigCompiler::m_ZoneDirs; ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone, const String& package) : m_Path(path), m_Input(input), m_Zone(zone), m_Package(package), - m_Eof(false), m_OpenBraces(0), m_IgnoreNewlines(0) + m_Eof(false), m_OpenBraces(0) { InitializeScanner(); } diff --git a/lib/config/configcompiler.hpp b/lib/config/configcompiler.hpp index 85cb6cced..b216b12a1 100644 --- a/lib/config/configcompiler.hpp +++ b/lib/config/configcompiler.hpp @@ -141,10 +141,10 @@ public: bool m_Eof; int m_OpenBraces; - int m_IgnoreNewlines; std::ostringstream m_LexBuffer; CompilerDebugInfo m_LocationBegin; + std::stack m_IgnoreNewlines; std::stack m_Apply; std::stack m_ObjectAssign; std::stack m_SeenAssign; diff --git a/test/config-ops.cpp b/test/config-ops.cpp index 227abe4b1..41f500c93 100644 --- a/test/config-ops.cpp +++ b/test/config-ops.cpp @@ -204,6 +204,10 @@ BOOST_AUTO_TEST_CASE(simple) expr = ConfigCompiler::CompileText("", "\"\\'test\""); BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError); delete expr; + + expr = ConfigCompiler::CompileText("", "({ a = 3\nb = 3 })"); + BOOST_CHECK(expr->Evaluate(frame).GetValue().IsObjectType()); + delete expr; } BOOST_AUTO_TEST_CASE(advanced)