From 252f3205cbf3e97803e91be7f42ee85c61ace49e Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 15 Dec 2014 12:57:40 +0100 Subject: [PATCH] Fix incorrect variable scoping refs #8074 --- lib/base/scriptglobal.cpp | 5 ++++ lib/base/scriptglobal.hpp | 1 + lib/config/config_parser.yy | 5 ++-- lib/config/expression.cpp | 46 +++++++++++++++++++++++++++++++++++-- lib/config/expression.hpp | 8 +++++-- lib/config/vmops.hpp | 3 --- 6 files changed, 59 insertions(+), 9 deletions(-) diff --git a/lib/base/scriptglobal.cpp b/lib/base/scriptglobal.cpp index 9ffa689cd..cf2b26914 100644 --- a/lib/base/scriptglobal.cpp +++ b/lib/base/scriptglobal.cpp @@ -50,6 +50,11 @@ void ScriptGlobal::Set(const String& name, const Value& value) m_Globals->Set(name, value); } +bool ScriptGlobal::Exists(const String& name) +{ + return m_Globals->Contains(name); +} + Dictionary::Ptr ScriptGlobal::GetGlobals(void) { return m_Globals; diff --git a/lib/base/scriptglobal.hpp b/lib/base/scriptglobal.hpp index 2c2af1bfb..abccf02da 100644 --- a/lib/base/scriptglobal.hpp +++ b/lib/base/scriptglobal.hpp @@ -36,6 +36,7 @@ class I2_BASE_API ScriptGlobal public: static Value Get(const String& name, const Value *defaultValue = NULL); static void Set(const String& name, const Value& value); + static bool Exists(const String& name); static void WriteToFile(const String& filename); diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 2522bca5e..0c0534da4 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -559,7 +559,6 @@ lterm: type | rterm combined_set_op rterm { Expression *expr = $1; - BindToScope(expr, ScopeCurrent); $$ = new SetExpression(expr, $2, $3, DebugInfoRange(@1, @3)); } | T_INCLUDE T_STRING @@ -787,7 +786,9 @@ rterm: T_STRING } | rterm_scope { - $$ = $1; + Expression *expr = $1; + BindToScope(expr, ScopeCurrent); + $$ = expr; } | '(' { diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index 204064144..a2cc2b09f 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -94,12 +94,37 @@ const DebugInfo& DebuggableExpression::GetDebugInfo(void) const Value VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { - return VMOps::Variable(frame, m_Variable, m_DebugInfo); + if (frame.Locals && frame.Locals->Contains(m_Variable)) + return frame.Locals->Get(m_Variable); + else if (frame.Self.IsObject() && frame.Locals != static_cast(frame.Self) && VMOps::HasField(frame.Self, m_Variable)) + return VMOps::GetField(frame.Self, m_Variable, m_DebugInfo); + else + return ScriptGlobal::Get(m_Variable); } bool VariableExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const { - return false; + *index = m_Variable; + + if (frame.Locals && frame.Locals->Contains(m_Variable)) { + *parent = frame.Locals; + + if (dhint) + *dhint = NULL; + } else if (frame.Self.IsObject() && frame.Locals != static_cast(frame.Self) && VMOps::HasField(frame.Self, m_Variable)) { + *parent = frame.Self; + + if (dhint && *dhint) + *dhint = new DebugHint((*dhint)->GetChild(m_Variable)); + } else if (ScriptGlobal::Exists(m_Variable)) { + *parent = ScriptGlobal::GetGlobals(); + + if (dhint) + *dhint = NULL; + } else + *parent = frame.Locals; + + return true; } Value NegateExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const @@ -410,6 +435,23 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value * void icinga::BindToScope(Expression *& expr, ScopeSpecifier scopeSpec) { + DictExpression *dexpr = dynamic_cast(expr); + + if (dexpr) { + BOOST_FOREACH(Expression *& expr, dexpr->m_Expressions) + BindToScope(expr, scopeSpec); + + return; + } + + SetExpression *aexpr = dynamic_cast(expr); + + if (aexpr) { + BindToScope(aexpr->m_Operand1, scopeSpec); + + return; + } + IndexerExpression *iexpr = dynamic_cast(expr); if (iexpr) { diff --git a/lib/config/expression.hpp b/lib/config/expression.hpp index a450829cc..7165658b1 100644 --- a/lib/config/expression.hpp +++ b/lib/config/expression.hpp @@ -280,7 +280,7 @@ protected: private: String m_Variable; - friend void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); + friend I2_CONFIG_API void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); }; class I2_CONFIG_API NegateExpression : public UnaryExpression @@ -589,6 +589,8 @@ protected: private: std::vector m_Expressions; bool m_Inline; + + friend I2_CONFIG_API void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); }; class I2_CONFIG_API SetExpression : public BinaryExpression @@ -603,6 +605,8 @@ protected: private: CombinedSetOp m_Op; + + friend I2_CONFIG_API void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); }; class I2_CONFIG_API ConditionalExpression : public DebuggableExpression @@ -664,7 +668,7 @@ protected: virtual Value DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const; virtual bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const; - friend void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); + friend I2_CONFIG_API void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); }; I2_CONFIG_API void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); diff --git a/lib/config/vmops.hpp b/lib/config/vmops.hpp index 3ad9ece00..be035d649 100644 --- a/lib/config/vmops.hpp +++ b/lib/config/vmops.hpp @@ -46,9 +46,6 @@ class VMOps public: static inline Value Variable(ScriptFrame& frame, const String& name, const DebugInfo& debugInfo = DebugInfo()) { - if (name == "this") - return frame.Self; - if (frame.Locals && frame.Locals->Contains(name)) return frame.Locals->Get(name); else if (frame.Self.IsObject() && frame.Locals != static_cast(frame.Self) && HasField(frame.Self, name)) -- 2.40.0