1 /******************************************************************************
3 * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License *
7 * as published by the Free Software Foundation; either version 2 *
8 * of the License, or (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software Foundation *
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ******************************************************************************/
20 #include "config/expression.hpp"
21 #include "config/configitem.hpp"
22 #include "config/configcompiler.hpp"
23 #include "config/vmops.hpp"
24 #include "base/array.hpp"
25 #include "base/json.hpp"
26 #include "base/object.hpp"
27 #include "base/logger.hpp"
28 #include "base/exception.hpp"
29 #include "base/scriptglobal.hpp"
30 #include "base/loader.hpp"
31 #include <boost/exception_ptr.hpp>
32 #include <boost/exception/errinfo_nested_exception.hpp>
34 using namespace icinga;
36 boost::signals2::signal<void (ScriptFrame&, ScriptError *ex, const DebugInfo&)> Expression::OnBreakpoint;
37 boost::thread_specific_ptr<bool> l_InBreakpointHandler;
39 Expression::~Expression(void)
42 void Expression::ScriptBreakpoint(ScriptFrame& frame, ScriptError *ex, const DebugInfo& di)
44 bool *inHandler = l_InBreakpointHandler.get();
45 if (!inHandler || !*inHandler) {
46 inHandler = new bool(true);
47 l_InBreakpointHandler.reset(inHandler);
48 OnBreakpoint(frame, ex, di);
53 ExpressionResult Expression::Evaluate(ScriptFrame& frame, DebugHint *dhint) const
57 /* std::ostringstream msgbuf;
58 ShowCodeLocation(msgbuf, GetDebugInfo(), false);
59 Log(LogDebug, "Expression")
60 << "Executing:\n" << msgbuf.str();*/
63 frame.IncreaseStackDepth();
64 ExpressionResult result = DoEvaluate(frame, dhint);
65 frame.DecreaseStackDepth();
67 } catch (ScriptError& ex) {
68 frame.DecreaseStackDepth();
70 ScriptBreakpoint(frame, &ex, GetDebugInfo());
72 } catch (const std::exception& ex) {
73 frame.DecreaseStackDepth();
75 BOOST_THROW_EXCEPTION(ScriptError("Error while evaluating expression: " + String(ex.what()), GetDebugInfo())
76 << boost::errinfo_nested_exception(boost::current_exception()));
79 frame.DecreaseStackDepth();
82 bool Expression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const
87 const DebugInfo& Expression::GetDebugInfo(void) const
89 static DebugInfo debugInfo;
93 std::unique_ptr<Expression> icinga::MakeIndexer(ScopeSpecifier scopeSpec, const String& index)
95 std::unique_ptr<Expression> scope{new GetScopeExpression(scopeSpec)};
96 return std::unique_ptr<Expression>(new IndexerExpression(std::move(scope), MakeLiteral(index)));
99 void DictExpression::MakeInline(void)
104 LiteralExpression::LiteralExpression(const Value& value)
108 ExpressionResult LiteralExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
113 const DebugInfo& DebuggableExpression::GetDebugInfo(void) const
118 ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
122 if (frame.Locals && frame.Locals->Get(m_Variable, &value))
124 else if (frame.Self.IsObject() && frame.Locals != frame.Self.Get<Object::Ptr>() && frame.Self.Get<Object::Ptr>()->GetOwnField(m_Variable, &value))
126 else if (VMOps::FindVarImport(frame, m_Variable, &value, m_DebugInfo))
129 return ScriptGlobal::Get(m_Variable);
132 bool VariableExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const
136 if (frame.Locals && frame.Locals->Contains(m_Variable)) {
137 *parent = frame.Locals;
141 } else if (frame.Self.IsObject() && frame.Locals != frame.Self.Get<Object::Ptr>() && frame.Self.Get<Object::Ptr>()->HasOwnField(m_Variable)) {
142 *parent = frame.Self;
145 *dhint = new DebugHint((*dhint)->GetChild(m_Variable));
146 } else if (VMOps::FindVarImportRef(frame, m_Variable, parent, m_DebugInfo)) {
148 } else if (ScriptGlobal::Exists(m_Variable)) {
149 *parent = ScriptGlobal::GetGlobals();
154 *parent = frame.Self;
159 ExpressionResult NegateExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
161 ExpressionResult operand = m_Operand->Evaluate(frame);
162 CHECK_RESULT(operand);
164 return ~(long)operand.GetValue();
167 ExpressionResult LogicalNegateExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
169 ExpressionResult operand = m_Operand->Evaluate(frame);
170 CHECK_RESULT(operand);
172 return !operand.GetValue().ToBool();
175 ExpressionResult AddExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
177 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
178 CHECK_RESULT(operand1);
180 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
181 CHECK_RESULT(operand2);
183 return operand1.GetValue() + operand2.GetValue();
186 ExpressionResult SubtractExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
188 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
189 CHECK_RESULT(operand1);
191 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
192 CHECK_RESULT(operand2);
194 return operand1.GetValue() - operand2.GetValue();
197 ExpressionResult MultiplyExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
199 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
200 CHECK_RESULT(operand1);
202 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
203 CHECK_RESULT(operand2);
205 return operand1.GetValue() * operand2.GetValue();
208 ExpressionResult DivideExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
210 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
211 CHECK_RESULT(operand1);
213 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
214 CHECK_RESULT(operand2);
216 return operand1.GetValue() / operand2.GetValue();
219 ExpressionResult ModuloExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
221 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
222 CHECK_RESULT(operand1);
224 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
225 CHECK_RESULT(operand2);
227 return operand1.GetValue() % operand2.GetValue();
230 ExpressionResult XorExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
232 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
233 CHECK_RESULT(operand1);
235 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
236 CHECK_RESULT(operand2);
238 return operand1.GetValue() ^ operand2.GetValue();
241 ExpressionResult BinaryAndExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
243 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
244 CHECK_RESULT(operand1);
246 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
247 CHECK_RESULT(operand2);
249 return operand1.GetValue() & operand2.GetValue();
252 ExpressionResult BinaryOrExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
254 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
255 CHECK_RESULT(operand1);
257 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
258 CHECK_RESULT(operand2);
260 return operand1.GetValue() | operand2.GetValue();
263 ExpressionResult ShiftLeftExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
265 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
266 CHECK_RESULT(operand1);
268 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
269 CHECK_RESULT(operand2);
271 return operand1.GetValue() << operand2.GetValue();
274 ExpressionResult ShiftRightExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
276 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
277 CHECK_RESULT(operand1);
279 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
280 CHECK_RESULT(operand2);
282 return operand1.GetValue() >> operand2.GetValue();
285 ExpressionResult EqualExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
287 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
288 CHECK_RESULT(operand1);
290 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
291 CHECK_RESULT(operand2);
293 return operand1.GetValue() == operand2.GetValue();
296 ExpressionResult NotEqualExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
298 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
299 CHECK_RESULT(operand1);
301 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
302 CHECK_RESULT(operand2);
304 return operand1.GetValue() != operand2.GetValue();
307 ExpressionResult LessThanExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
309 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
310 CHECK_RESULT(operand1);
312 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
313 CHECK_RESULT(operand2);
315 return operand1.GetValue() < operand2.GetValue();
318 ExpressionResult GreaterThanExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
320 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
321 CHECK_RESULT(operand1);
323 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
324 CHECK_RESULT(operand2);
326 return operand1.GetValue() > operand2.GetValue();
329 ExpressionResult LessThanOrEqualExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
331 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
332 CHECK_RESULT(operand1);
334 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
335 CHECK_RESULT(operand2);
337 return operand1.GetValue() <= operand2.GetValue();
340 ExpressionResult GreaterThanOrEqualExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
342 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
343 CHECK_RESULT(operand1);
345 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
346 CHECK_RESULT(operand2);
348 return operand1.GetValue() >= operand2.GetValue();
351 ExpressionResult InExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
353 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
354 CHECK_RESULT(operand2);
356 if (operand2.GetValue().IsEmpty())
358 else if (!operand2.GetValue().IsObjectType<Array>())
359 BOOST_THROW_EXCEPTION(ScriptError("Invalid right side argument for 'in' operator: " + JsonEncode(operand2.GetValue()), m_DebugInfo));
361 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
362 CHECK_RESULT(operand1)
364 Array::Ptr arr = operand2.GetValue();
365 return arr->Contains(operand1.GetValue());
368 ExpressionResult NotInExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
370 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
371 CHECK_RESULT(operand2);
373 if (operand2.GetValue().IsEmpty())
375 else if (!operand2.GetValue().IsObjectType<Array>())
376 BOOST_THROW_EXCEPTION(ScriptError("Invalid right side argument for 'in' operator: " + JsonEncode(operand2.GetValue()), m_DebugInfo));
378 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
379 CHECK_RESULT(operand1);
381 Array::Ptr arr = operand2.GetValue();
382 return !arr->Contains(operand1.GetValue());
385 ExpressionResult LogicalAndExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
387 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
388 CHECK_RESULT(operand1);
390 if (!operand1.GetValue().ToBool())
393 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
394 CHECK_RESULT(operand2);
396 return operand2.GetValue();
400 ExpressionResult LogicalOrExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
402 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
403 CHECK_RESULT(operand1);
405 if (operand1.GetValue().ToBool())
408 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
409 CHECK_RESULT(operand2);
411 return operand2.GetValue();
415 ExpressionResult FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
420 if (m_FName->GetReference(frame, false, &self, &index))
421 vfunc = VMOps::GetField(self, index, frame.Sandboxed, m_DebugInfo);
423 ExpressionResult vfuncres = m_FName->Evaluate(frame);
424 CHECK_RESULT(vfuncres);
426 vfunc = vfuncres.GetValue();
429 if (vfunc.IsObjectType<Type>()) {
430 std::vector<Value> arguments;
431 arguments.reserve(m_Args.size());
432 for (const auto& arg : m_Args) {
433 ExpressionResult argres = arg->Evaluate(frame);
434 CHECK_RESULT(argres);
436 arguments.push_back(argres.GetValue());
439 return VMOps::ConstructorCall(vfunc, arguments, m_DebugInfo);
442 if (!vfunc.IsObjectType<Function>())
443 BOOST_THROW_EXCEPTION(ScriptError("Argument is not a callable object.", m_DebugInfo));
445 Function::Ptr func = vfunc;
447 if (!func->IsSideEffectFree() && frame.Sandboxed)
448 BOOST_THROW_EXCEPTION(ScriptError("Function is not marked as safe for sandbox mode.", m_DebugInfo));
450 std::vector<Value> arguments;
451 arguments.reserve(m_Args.size());
452 for (const auto& arg : m_Args) {
453 ExpressionResult argres = arg->Evaluate(frame);
454 CHECK_RESULT(argres);
456 arguments.push_back(argres.GetValue());
459 return VMOps::FunctionCall(frame, self, func, arguments);
462 ExpressionResult ArrayExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
464 Array::Ptr result = new Array();
465 result->Reserve(m_Expressions.size());
467 for (const auto& aexpr : m_Expressions) {
468 ExpressionResult element = aexpr->Evaluate(frame);
469 CHECK_RESULT(element);
471 result->Add(element.GetValue());
477 ExpressionResult DictExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
483 frame.Self = new Dictionary();
489 for (const auto& aexpr : m_Expressions) {
490 ExpressionResult element = aexpr->Evaluate(frame, m_Inline ? dhint : nullptr);
491 CHECK_RESULT(element);
492 result = element.GetValue();
496 std::swap(self, frame.Self);
503 std::swap(self, frame.Self);
508 ExpressionResult GetScopeExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
510 if (m_ScopeSpec == ScopeLocal)
512 else if (m_ScopeSpec == ScopeThis)
514 else if (m_ScopeSpec == ScopeGlobal)
515 return ScriptGlobal::GetGlobals();
517 VERIFY(!"Invalid scope.");
520 ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
523 BOOST_THROW_EXCEPTION(ScriptError("Assignments are not allowed in sandbox mode.", m_DebugInfo));
525 DebugHint *psdhint = dhint;
530 if (!m_Operand1->GetReference(frame, true, &parent, &index, &psdhint))
531 BOOST_THROW_EXCEPTION(ScriptError("Expression cannot be assigned to.", m_DebugInfo));
533 ExpressionResult operand2 = m_Operand2->Evaluate(frame, dhint);
534 CHECK_RESULT(operand2);
536 if (m_Op != OpSetLiteral) {
537 Value object = VMOps::GetField(parent, index, frame.Sandboxed, m_DebugInfo);
541 operand2 = object + operand2;
544 operand2 = object - operand2;
547 operand2 = object * operand2;
550 operand2 = object / operand2;
553 operand2 = object % operand2;
556 operand2 = object ^ operand2;
559 operand2 = object & operand2;
562 operand2 = object | operand2;
565 VERIFY(!"Invalid opcode.");
569 VMOps::SetField(parent, index, operand2.GetValue(), m_DebugInfo);
572 psdhint->AddMessage("=", m_DebugInfo);
574 if (psdhint != dhint)
581 ExpressionResult ConditionalExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
583 ExpressionResult condition = m_Condition->Evaluate(frame, dhint);
584 CHECK_RESULT(condition);
586 if (condition.GetValue().ToBool())
587 return m_TrueBranch->Evaluate(frame, dhint);
588 else if (m_FalseBranch)
589 return m_FalseBranch->Evaluate(frame, dhint);
594 ExpressionResult WhileExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
597 BOOST_THROW_EXCEPTION(ScriptError("While loops are not allowed in sandbox mode.", m_DebugInfo));
600 ExpressionResult condition = m_Condition->Evaluate(frame, dhint);
601 CHECK_RESULT(condition);
603 if (!condition.GetValue().ToBool())
606 ExpressionResult loop_body = m_LoopBody->Evaluate(frame, dhint);
607 CHECK_RESULT_LOOP(loop_body);
613 ExpressionResult ReturnExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
615 ExpressionResult operand = m_Operand->Evaluate(frame);
616 CHECK_RESULT(operand);
618 return ExpressionResult(operand.GetValue(), ResultReturn);
621 ExpressionResult BreakExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
623 return ExpressionResult(Empty, ResultBreak);
626 ExpressionResult ContinueExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
628 return ExpressionResult(Empty, ResultContinue);
631 ExpressionResult IndexerExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
633 ExpressionResult operand1 = m_Operand1->Evaluate(frame, dhint);
634 CHECK_RESULT(operand1);
636 ExpressionResult operand2 = m_Operand2->Evaluate(frame, dhint);
637 CHECK_RESULT(operand2);
639 return VMOps::GetField(operand1.GetValue(), operand2.GetValue(), frame.Sandboxed, m_DebugInfo);
642 bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const
646 DebugHint *psdhint = nullptr;
647 bool free_psd = false;
655 if (m_Operand1->GetReference(frame, init_dict, &vparent, &vindex, &psdhint)) {
657 Value old_value = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_Operand1->GetDebugInfo());
659 if (old_value.IsEmpty() && !old_value.IsString())
660 VMOps::SetField(vparent, vindex, new Dictionary(), m_Operand1->GetDebugInfo());
663 *parent = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_DebugInfo);
666 ExpressionResult operand1 = m_Operand1->Evaluate(frame);
667 *parent = operand1.GetValue();
670 ExpressionResult operand2 = m_Operand2->Evaluate(frame);
671 *index = operand2.GetValue();
675 *dhint = new DebugHint(psdhint->GetChild(*index));
686 void icinga::BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec)
688 DictExpression *dexpr = dynamic_cast<DictExpression *>(expr.get());
691 for (auto& expr : dexpr->m_Expressions)
692 BindToScope(expr, scopeSpec);
697 SetExpression *aexpr = dynamic_cast<SetExpression *>(expr.get());
700 BindToScope(aexpr->m_Operand1, scopeSpec);
705 IndexerExpression *iexpr = dynamic_cast<IndexerExpression *>(expr.get());
708 BindToScope(iexpr->m_Operand1, scopeSpec);
712 LiteralExpression *lexpr = dynamic_cast<LiteralExpression *>(expr.get());
714 if (lexpr && lexpr->GetValue().IsString()) {
715 std::unique_ptr<Expression> scope{new GetScopeExpression(scopeSpec)};
716 expr.reset(new IndexerExpression(std::move(scope), std::move(expr), lexpr->GetDebugInfo()));
719 VariableExpression *vexpr = dynamic_cast<VariableExpression *>(expr.get());
722 std::unique_ptr<Expression> scope{new GetScopeExpression(scopeSpec)};
723 expr.reset(new IndexerExpression(std::move(scope), MakeLiteral(vexpr->GetVariable()), vexpr->GetDebugInfo()));
727 ExpressionResult ThrowExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
729 ExpressionResult messageres = m_Message->Evaluate(frame);
730 CHECK_RESULT(messageres);
731 Value message = messageres.GetValue();
732 BOOST_THROW_EXCEPTION(ScriptError(message, m_DebugInfo, m_IncompleteExpr));
735 ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
738 BOOST_THROW_EXCEPTION(ScriptError("Imports are not allowed in sandbox mode.", m_DebugInfo));
740 String type = VMOps::GetField(frame.Self, "type", frame.Sandboxed, m_DebugInfo);
741 ExpressionResult nameres = m_Name->Evaluate(frame);
742 CHECK_RESULT(nameres);
743 Value name = nameres.GetValue();
745 if (!name.IsString())
746 BOOST_THROW_EXCEPTION(ScriptError("Template/object name must be a string", m_DebugInfo));
748 ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(Type::GetByName(type), name);
751 BOOST_THROW_EXCEPTION(ScriptError("Import references unknown template: '" + name + "'", m_DebugInfo));
753 Dictionary::Ptr scope = item->GetScope();
756 scope->CopyTo(frame.Locals);
758 ExpressionResult result = item->GetExpression()->Evaluate(frame, dhint);
759 CHECK_RESULT(result);
764 ExpressionResult ImportDefaultTemplatesExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
767 BOOST_THROW_EXCEPTION(ScriptError("Imports are not allowed in sandbox mode.", m_DebugInfo));
769 String type = VMOps::GetField(frame.Self, "type", frame.Sandboxed, m_DebugInfo);
770 Type::Ptr ptype = Type::GetByName(type);
772 for (const ConfigItem::Ptr& item : ConfigItem::GetDefaultTemplates(ptype)) {
773 Dictionary::Ptr scope = item->GetScope();
776 scope->CopyTo(frame.Locals);
778 ExpressionResult result = item->GetExpression()->Evaluate(frame, dhint);
779 CHECK_RESULT(result);
785 ExpressionResult FunctionExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
787 return VMOps::NewFunction(frame, m_Name, m_Args, m_ClosedVars, m_Expression);
790 ExpressionResult ApplyExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
793 BOOST_THROW_EXCEPTION(ScriptError("Apply rules are not allowed in sandbox mode.", m_DebugInfo));
795 ExpressionResult nameres = m_Name->Evaluate(frame);
796 CHECK_RESULT(nameres);
798 return VMOps::NewApply(frame, m_Type, m_Target, nameres.GetValue(), m_Filter,
799 m_Package, m_FKVar, m_FVVar, m_FTerm, m_ClosedVars, m_IgnoreOnError, m_Expression, m_DebugInfo);
802 ExpressionResult ObjectExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
805 BOOST_THROW_EXCEPTION(ScriptError("Object definitions are not allowed in sandbox mode.", m_DebugInfo));
807 ExpressionResult typeres = m_Type->Evaluate(frame, dhint);
808 CHECK_RESULT(typeres);
809 Type::Ptr type = typeres.GetValue();
814 ExpressionResult nameres = m_Name->Evaluate(frame, dhint);
815 CHECK_RESULT(nameres);
817 name = nameres.GetValue();
820 return VMOps::NewObject(frame, m_Abstract, type, name, m_Filter, m_Zone,
821 m_Package, m_DefaultTmpl, m_IgnoreOnError, m_ClosedVars, m_Expression, m_DebugInfo);
824 ExpressionResult ForExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
827 BOOST_THROW_EXCEPTION(ScriptError("For loops are not allowed in sandbox mode.", m_DebugInfo));
829 ExpressionResult valueres = m_Value->Evaluate(frame, dhint);
830 CHECK_RESULT(valueres);
832 return VMOps::For(frame, m_FKVar, m_FVVar, valueres.GetValue(), m_Expression, m_DebugInfo);
835 ExpressionResult LibraryExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
838 BOOST_THROW_EXCEPTION(ScriptError("Loading libraries is not allowed in sandbox mode.", m_DebugInfo));
840 ExpressionResult libres = m_Operand->Evaluate(frame, dhint);
841 CHECK_RESULT(libres);
843 Log(LogNotice, "config")
844 << "Ignoring explicit load request for library \"" << libres << "\".";
849 ExpressionResult IncludeExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
852 BOOST_THROW_EXCEPTION(ScriptError("Includes are not allowed in sandbox mode.", m_DebugInfo));
854 std::unique_ptr<Expression> expr;
855 String name, path, pattern;
860 ExpressionResult pathres = m_Path->Evaluate(frame, dhint);
861 CHECK_RESULT(pathres);
862 path = pathres.GetValue();
865 expr = ConfigCompiler::HandleInclude(m_RelativeBase, path, m_SearchIncludes, m_Zone, m_Package, m_DebugInfo);
868 case IncludeRecursive:
870 ExpressionResult pathres = m_Path->Evaluate(frame, dhint);
871 CHECK_RESULT(pathres);
872 path = pathres.GetValue();
876 ExpressionResult patternres = m_Pattern->Evaluate(frame, dhint);
877 CHECK_RESULT(patternres);
878 pattern = patternres.GetValue();
881 expr = ConfigCompiler::HandleIncludeRecursive(m_RelativeBase, path, pattern, m_Zone, m_Package, m_DebugInfo);
886 ExpressionResult nameres = m_Name->Evaluate(frame, dhint);
887 CHECK_RESULT(nameres);
888 name = nameres.GetValue();
892 ExpressionResult pathres = m_Path->Evaluate(frame, dhint);
893 CHECK_RESULT(pathres);
894 path = pathres.GetValue();
898 ExpressionResult patternres = m_Pattern->Evaluate(frame, dhint);
899 CHECK_RESULT(patternres);
900 pattern = patternres.GetValue();
903 expr = ConfigCompiler::HandleIncludeZones(m_RelativeBase, name, path, pattern, m_Package, m_DebugInfo);
907 ExpressionResult res(Empty);
910 res = expr->Evaluate(frame, dhint);
911 } catch (const std::exception&) {
918 ExpressionResult BreakpointExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
920 ScriptBreakpoint(frame, nullptr, GetDebugInfo());
925 ExpressionResult UsingExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
928 BOOST_THROW_EXCEPTION(ScriptError("Using directives are not allowed in sandbox mode.", m_DebugInfo));
930 ExpressionResult importres = m_Name->Evaluate(frame);
931 CHECK_RESULT(importres);
932 Value import = importres.GetValue();
934 if (!import.IsObjectType<Dictionary>())
935 BOOST_THROW_EXCEPTION(ScriptError("The parameter must resolve to an object of type 'Dictionary'", m_DebugInfo));
937 ScriptFrame::AddImport(import);
942 ExpressionResult TryExceptExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
945 ExpressionResult tryResult = m_TryBody->Evaluate(frame, dhint);
946 CHECK_RESULT(tryResult);
947 } catch (const std::exception&) {
948 ExpressionResult exceptResult = m_ExceptBody->Evaluate(frame, dhint);
949 CHECK_RESULT(exceptResult);