]> granicus.if.org Git - icinga2/commitdiff
Disallow side-effect-free r-value expressions in expression lists
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 8 Jan 2015 08:33:24 +0000 (09:33 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 8 Jan 2015 08:34:32 +0000 (09:34 +0100)
fixes #6570

lib/config/config_parser.yy

index 8747f415f13403cf752e25c88e352573a8d439ea..956921a96669003a22cc3d2dacf03f08959615fb 100644 (file)
@@ -187,6 +187,8 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
 %type <expr> rterm
 %type <expr> rterm_array
 %type <expr> rterm_scope
+%type <expr> rterm_side_effect
+%type <expr> rterm_no_side_effect
 %type <expr> lterm
 %type <expr> object
 %type <expr> apply
@@ -226,7 +228,7 @@ int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
 
 extern int yydebug;
 
-void yyerror(YYLTYPE *locp, std::vector<Expression *> *, ConfigCompiler *, const char *err)
+void yyerror(const YYLTYPE *locp, std::vector<Expression *> *, ConfigCompiler *, const char *err)
 {
        BOOST_THROW_EXCEPTION(ScriptError(err, *locp));
 }
@@ -652,10 +654,14 @@ lterm: type
                BindToScope(expr, ScopeLocal);
                $$ = new SetExpression(expr, $3, $4, DebugInfoRange(@1, @4));
        }
-       | rterm
+       | rterm_side_effect
        {
                $$ = $1;
        }
+       | rterm_no_side_effect
+       {
+               yyerror(&@1, NULL, NULL, "Value computed is not used.");        
+       }
        ;
        
 rterm_items: /* empty */
@@ -711,7 +717,52 @@ rterm_scope: '{' statements '}'
        }
        ;
 
-rterm: T_STRING
+rterm_side_effect: rterm '(' rterm_items ')'
+       {
+               $$ = new FunctionCallExpression($1, *$3, DebugInfoRange(@1, @4));
+               delete $3;
+       }
+       | identifier T_FOLLOWS rterm
+       {
+               DictExpression *aexpr = dynamic_cast<DictExpression *>($3);
+               if (aexpr)
+                       aexpr->MakeInline();
+
+               std::vector<String> args;
+               args.push_back($1);
+               free($1);
+
+               $$ = new FunctionExpression(args, new std::map<String, Expression *>(), $3, DebugInfoRange(@1, @3));
+       }
+       | '(' identifier_items ')' T_FOLLOWS rterm
+       {
+               DictExpression *aexpr = dynamic_cast<DictExpression *>($5);
+               if (aexpr)
+                       aexpr->MakeInline();
+
+               $$ = new FunctionExpression(*$2, new std::map<String, Expression *>(), $5, DebugInfoRange(@1, @5));
+               delete $2;
+       }
+       | T_IF '(' rterm ')' rterm_scope
+       {
+               DictExpression *atrue = dynamic_cast<DictExpression *>($5);
+               atrue->MakeInline();
+
+               $$ = new ConditionalExpression($3, atrue, NULL, DebugInfoRange(@1, @5));
+       }
+       | T_IF '(' rterm ')' rterm_scope T_ELSE rterm_scope
+       {
+               DictExpression *atrue = dynamic_cast<DictExpression *>($5);
+               atrue->MakeInline();
+
+               DictExpression *afalse = dynamic_cast<DictExpression *>($7);
+               afalse->MakeInline();
+
+               $$ = new ConditionalExpression($3, atrue, afalse, DebugInfoRange(@1, @7));
+       }
+       ;
+
+rterm_no_side_effect: T_STRING
        {
                $$ = MakeLiteral($1);
                free($1);
@@ -728,11 +779,6 @@ rterm: T_STRING
        {
                $$ = MakeLiteral();
        }
-       | rterm '(' rterm_items ')'
-       {
-               $$ = new FunctionCallExpression($1, *$3, DebugInfoRange(@1, @4));
-               delete $3;
-       }
        | rterm '.' T_IDENTIFIER %dprec 2
        {
                $$ = new IndexerExpression($1, MakeLiteral($3), DebugInfoRange(@1, @3));
@@ -768,9 +814,6 @@ rterm: T_STRING
                $$ = new GetScopeExpression(ScopeThis);
        }
        | rterm_array
-       {
-               $$ = $1;
-       }
        | rterm_scope
        {
                Expression *expr = $1;
@@ -814,44 +857,10 @@ rterm: T_STRING
                $$ = new FunctionExpression(*$3, $5, aexpr, DebugInfoRange(@1, @5));
                delete $3;
        }
-       | identifier T_FOLLOWS rterm
-       {
-               DictExpression *aexpr = dynamic_cast<DictExpression *>($3);
-               if (aexpr)
-                       aexpr->MakeInline();
-
-               std::vector<String> args;
-               args.push_back($1);
-               free($1);
-
-               $$ = new FunctionExpression(args, new std::map<String, Expression *>(), $3, DebugInfoRange(@1, @3));
-       }
-       | '(' identifier_items ')' T_FOLLOWS rterm
-       {
-               DictExpression *aexpr = dynamic_cast<DictExpression *>($5);
-               if (aexpr)
-                       aexpr->MakeInline();
-
-               $$ = new FunctionExpression(*$2, new std::map<String, Expression *>(), $5, DebugInfoRange(@1, @5));
-               delete $2;
-       }
-       | T_IF '(' rterm ')' rterm_scope
-       {
-               DictExpression *atrue = dynamic_cast<DictExpression *>($5);
-               atrue->MakeInline();
-
-               $$ = new ConditionalExpression($3, atrue, NULL, DebugInfoRange(@1, @5));
-       }
-       | T_IF '(' rterm ')' rterm_scope T_ELSE rterm_scope
-       {
-               DictExpression *atrue = dynamic_cast<DictExpression *>($5);
-               atrue->MakeInline();
-
-               DictExpression *afalse = dynamic_cast<DictExpression *>($7);
-               afalse->MakeInline();
+       ;
 
-               $$ = new ConditionalExpression($3, atrue, afalse, DebugInfoRange(@1, @7));
-       }
+rterm: rterm_side_effect
+       | rterm_no_side_effect
        ;
 
 target_type_specifier: /* empty */