Make sure that operator % throws an exception when the ride-hand-side argument is 0

fixes #8089
This commit is contained in:
Gunnar Beutner 2014-12-16 08:52:32 +01:00
parent 8ef8316ca6
commit 23a556c7ce
3 changed files with 77 additions and 6 deletions

View 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()))

View 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);

View 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