]> granicus.if.org Git - icinga2/commitdiff
Make sure that operator % throws an exception when the ride-hand-side argument is 0
authorGunnar Beutner <gunnar@beutner.name>
Tue, 16 Dec 2014 07:52:32 +0000 (08:52 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Tue, 16 Dec 2014 07:52:32 +0000 (08:52 +0100)
fixes #8089

lib/base/value-operators.cpp
lib/base/value.hpp
lib/config/expression.cpp

index ca3d8790291e5c8999bd359e87369f7d6e44843b..2ef1541c84f5db6fa10fe44288fe8fa6994a046e 100644 (file)
@@ -336,11 +336,9 @@ Value icinga::operator*(int lhs, const Value& rhs)
 
 Value icinga::operator/(const Value& lhs, const Value& rhs)
 {
-       if (lhs.IsEmpty())
-               return 0;
-       else if (rhs.IsEmpty())
+       if (rhs.IsEmpty())
                BOOST_THROW_EXCEPTION(std::invalid_argument("Right-hand side argument for operator / is Empty."));
-       else if (lhs.IsNumber() && rhs.IsNumber()) {
+       else if ((lhs.IsEmpty() || lhs.IsNumber()) && rhs.IsNumber()) {
                if (static_cast<double>(rhs) == 0)
                        BOOST_THROW_EXCEPTION(std::invalid_argument("Right-hand side argument for operator / is 0."));
 
@@ -369,6 +367,67 @@ Value icinga::operator/(int lhs, const Value& rhs)
        return Value(lhs) / rhs;
 }
 
+Value icinga::operator%(const Value& lhs, const Value& rhs)
+{
+       if (rhs.IsEmpty())
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Right-hand side argument for operator % is Empty."));
+       else if ((rhs.IsNumber() || lhs.IsNumber()) && rhs.IsNumber()) {
+               if (static_cast<double>(rhs) == 0)
+                       BOOST_THROW_EXCEPTION(std::invalid_argument("Right-hand side argument for operator % is 0."));
+
+               return static_cast<int>(lhs) % static_cast<int>(rhs);
+       } else
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Operator % cannot be applied to values of type '" + lhs.GetTypeName() + "' and '" + rhs.GetTypeName() + "'"));
+}
+
+Value icinga::operator%(const Value& lhs, double rhs)
+{
+       return lhs % Value(rhs);
+}
+
+Value icinga::operator%(double lhs, const Value& rhs)
+{
+       return Value(lhs) % rhs;
+}
+
+Value icinga::operator%(const Value& lhs, int rhs)
+{
+       return lhs % Value(rhs);
+}
+
+Value icinga::operator%(int lhs, const Value& rhs)
+{
+       return Value(lhs) % rhs;
+}
+
+Value icinga::operator^(const Value& lhs, const Value& rhs)
+{
+       if ((lhs.IsNumber() || lhs.IsEmpty()) && (rhs.IsNumber() || rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty()))
+               return static_cast<int>(lhs) ^ static_cast<int>(rhs);
+       else
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Operator & cannot be applied to values of type '" + lhs.GetTypeName() + "' and '" + rhs.GetTypeName() + "'"));
+}
+
+Value icinga::operator^(const Value& lhs, double rhs)
+{
+       return lhs & Value(rhs);
+}
+
+Value icinga::operator^(double lhs, const Value& rhs)
+{
+       return Value(lhs) & rhs;
+}
+
+Value icinga::operator^(const Value& lhs, int rhs)
+{
+       return lhs & Value(rhs);
+}
+
+Value icinga::operator^(int lhs, const Value& rhs)
+{
+       return Value(lhs) & rhs;
+}
+
 Value icinga::operator&(const Value& lhs, const Value& rhs)
 {
        if ((lhs.IsNumber() || lhs.IsEmpty()) && (rhs.IsNumber() || rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty()))
index 58b8b0375fb01d0f8a608fc53a1de3388edc36ef..0e3a6123a798830409f396178dcf0c8268a9fa9c 100644 (file)
@@ -278,6 +278,18 @@ I2_BASE_API Value operator/(double lhs, const Value& rhs);
 I2_BASE_API Value operator/(const Value& lhs, int rhs);
 I2_BASE_API Value operator/(int lhs, const Value& rhs);
 
+I2_BASE_API Value operator%(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator%(const Value& lhs, double rhs);
+I2_BASE_API Value operator%(double lhs, const Value& rhs);
+I2_BASE_API Value operator%(const Value& lhs, int rhs);
+I2_BASE_API Value operator%(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator^(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator^(const Value& lhs, double rhs);
+I2_BASE_API Value operator^(double lhs, const Value& rhs);
+I2_BASE_API Value operator^(const Value& lhs, int rhs);
+I2_BASE_API Value operator^(int lhs, const Value& rhs);
+
 I2_BASE_API Value operator&(const Value& lhs, const Value& rhs);
 I2_BASE_API Value operator&(const Value& lhs, double rhs);
 I2_BASE_API Value operator&(double lhs, const Value& rhs);
index e6bdcf4d172d0f16b8a40ff371556002958226a2..c4ad058ca9f3488995bb84cecf5d567b351e4903 100644 (file)
@@ -159,12 +159,12 @@ Value DivideExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
 
 Value ModuloExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
 {
-       return (long)m_Operand1->Evaluate(frame) % (long)m_Operand2->Evaluate(frame);
+       return m_Operand1->Evaluate(frame) % m_Operand2->Evaluate(frame);
 }
 
 Value XorExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
 {
-       return (long)m_Operand1->Evaluate(frame) ^ (long)m_Operand2->Evaluate(frame);
+       return m_Operand1->Evaluate(frame) ^ m_Operand2->Evaluate(frame);
 }
 
 Value BinaryAndExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const