/// <inheritdoc /> public override void VisitIntegerValue(IntegerValue value) { switch (operation) { case Operations.Identical: result = Comparison.Equal(OutSet, leftOperand, value.Value); break; case Operations.NotIdentical: result = Comparison.NotEqual(OutSet, leftOperand, value.Value); break; case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand, value.Value); break; default: result = Comparison.IntervalCompare(OutSet, operation, leftOperand, value.Value); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand, value.Value); if (result != null) { break; } base.VisitIntegerValue(value); break; } }
/// <inheritdoc /> public override void VisitStringValue(StringValue value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToNativeInteger(Snapshot, leftOperand), value.Value); break; default: result = Comparison.LeftAlwaysGreater(OutSet, operation); if (result != null) { break; } var leftBoolean = TypeConversion.ToNativeBoolean(Snapshot, leftOperand); var rightBoolean = TypeConversion.ToBoolean(value.Value); result = LogicalOperation.Logical(OutSet, operation, leftBoolean, rightBoolean); if (result != null) { break; } result = BitwiseOperation.Bitwise(OutSet, operation, TypeConversion.ToNativeInteger(Snapshot, leftOperand), value.Value); if (result == null) { base.VisitStringValue(value); } break; } }
/// <inheritdoc /> public override void VisitIntervalIntegerValue(IntegerIntervalValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.BitOr: case Operations.BitXor: result = value; break; case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand), value); break; default: result = ArithmeticOperation.Arithmetic(flow, operation, TypeConversion.ToInteger(leftOperand), value); if (result != null) { break; } base.VisitIntervalIntegerValue(value); break; } }
/// <inheritdoc /> public override void VisitIntervalFloatValue(FloatIntervalValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.BitOr: case Operations.BitXor: IntervalValue <int> integerInterval; if (TypeConversion.TryConvertToIntegerInterval(OutSet, value, out integerInterval)) { result = integerInterval; } else { result = OutSet.AnyIntegerValue; } break; case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand), value); break; default: result = ArithmeticOperation.Arithmetic(flow, operation, TypeConversion.ToFloat(leftOperand), value); if (result != null) { break; } base.VisitIntervalFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitStringValue(StringValue value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand, value.Value); break; default: int integerValue; double floatValue; bool isInteger; TypeConversion.TryConvertToNumber(value.Value, true, out integerValue, out floatValue, out isInteger); result = Comparison.IntervalCompare(OutSet, operation, leftOperand, floatValue); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand, floatValue); if (result != null) { break; } base.VisitStringValue(value); break; } }
/// <inheritdoc /> public override void VisitIntervalFloatValue(FloatIntervalValue value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand.Value), value); break; default: var leftFloat = TypeConversion.ToFloat(leftOperand.Value); result = Comparison.IntervalCompare(OutSet, operation, leftFloat, value); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftFloat, value); if (result != null) { break; } result = LogicalOperation.Logical(OutSet, operation, leftOperand.Value, value); if (result != null) { break; } base.VisitIntervalFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitIntervalFloatValue(FloatIntervalValue value) { switch (operation) { case Operations.Identical: result = OutSet.CreateBool(false); break; case Operations.NotIdentical: result = OutSet.CreateBool(true); break; case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand, value); break; default: var floatInterval = TypeConversion.ToFloatInterval(OutSet, leftOperand); result = Comparison.IntervalCompare(OutSet, operation, floatInterval, value); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand, value); if (result != null) { break; } base.VisitIntervalFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitAssociativeArray(AssociativeArray value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand.Value, TypeConversion.ToNativeInteger(Snapshot, value)); break; default: result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToBoolean(leftOperand.Value), TypeConversion.ToNativeBoolean(Snapshot, value)); if (result != null) { break; } result = BitwiseOperation.Bitwise(OutSet, operation, leftOperand.Value, TypeConversion.ToNativeInteger(Snapshot, value)); if (result != null) { break; } base.VisitAssociativeArray(value); break; } }
/// <inheritdoc /> public override void VisitIntervalIntegerValue(IntegerIntervalValue value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand.Value, value); break; default: result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToBoolean(leftOperand.Value), value); if (result != null) { break; } int integerValue; double floatValue; bool isInteger; TypeConversion.TryConvertToNumber(leftOperand.Value, true, out integerValue, out floatValue, out isInteger); if (isInteger) { result = Comparison.IntervalCompare(OutSet, operation, integerValue, value); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, integerValue, value); if (result != null) { break; } } else { var floatInterval = TypeConversion.ToFloatInterval(OutSet, value); result = Comparison.IntervalCompare(OutSet, operation, floatValue, floatInterval); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, floatValue, floatInterval); if (result != null) { break; } } base.VisitIntervalIntegerValue(value); break; } }
/// <inheritdoc /> public override void VisitAssociativeArray(AssociativeArray value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand, TypeConversion.ToNativeInteger(Snapshot, value)); break; default: base.VisitAssociativeArray(value); break; } }
/// <inheritdoc /> public override void VisitFloatValue(FloatValue value) { switch (operation) { case Operations.Identical: SetWarning("Comparing floating-point numbers directly for equality"); result = OutSet.CreateBool(leftOperand.Value == value.Value); break; case Operations.NotIdentical: SetWarning("Comparing floating-point numbers directly for non-equality"); result = OutSet.CreateBool(leftOperand.Value != value.Value); break; case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand.Value, value.Value); break; default: result = Comparison.Compare(OutSet, operation, leftOperand.Value, value.Value); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand.Value, value.Value); if (result != null) { break; } result = BitwiseOperation.Bitwise(OutSet, operation, leftOperand.Value, value.Value); if (result != null) { break; } result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToBoolean(leftOperand.Value), TypeConversion.ToBoolean(value.Value)); if (result != null) { break; } base.VisitFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitIntegerValue(IntegerValue value) { switch (operation) { case Operations.Identical: result = OutSet.CreateBool(leftOperand.Value == value.Value); break; case Operations.NotIdentical: result = OutSet.CreateBool(leftOperand.Value != value.Value); break; case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand.Value, value.Value); break; default: result = Comparison.Compare(OutSet, operation, leftOperand.Value, value.Value); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand.Value, value.Value); if (result != null) { break; } result = BitwiseOperation.Bitwise(OutSet, operation, leftOperand.Value, value.Value); if (result != null) { break; } result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToBoolean(leftOperand.Value), TypeConversion.ToBoolean(value.Value)); if (result != null) { break; } base.VisitIntegerValue(value); break; } }
/// <inheritdoc /> public override void VisitStringValue(StringValue value) { switch (operation) { case Operations.Or: case Operations.Xor: result = TypeConversion.ToBoolean(OutSet, value); break; case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand), value.Value); break; case Operations.BitOr: case Operations.BitXor: result = TypeConversion.ToInteger(OutSet, value); break; default: result = Comparison.Compare(OutSet, operation, string.Empty, value.Value); if (result != null) { break; } int integerValue; double floatValue; bool isInteger; TypeConversion.TryConvertToNumber(value.Value, true, out integerValue, out floatValue, out isInteger); var leftInteger = TypeConversion.ToInteger(leftOperand); result = isInteger ? ArithmeticOperation.Arithmetic(flow, operation, leftInteger, integerValue) : ArithmeticOperation.Arithmetic(flow, operation, leftInteger, floatValue); if (result != null) { break; } base.VisitStringValue(value); break; } }
/// <inheritdoc /> public override void VisitAssociativeArray(AssociativeArray value) { switch (operation) { case Operations.Identical: case Operations.NotIdentical: // TODO: They must be the same and indices must be in the same order result = OutSet.AnyBooleanValue; break; case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToNativeInteger(Snapshot, leftOperand), TypeConversion.ToNativeInteger(Snapshot, value)); break; default: if (Comparison.IsOperationComparison(operation)) { // TODO: We compare arrays first by the number of elements and second // if key from left operand is not found in right operand then arrays are // uncomparable, otherwise we compare value by value result = OutSet.AnyBooleanValue; break; } result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToNativeBoolean(Snapshot, leftOperand), TypeConversion.ToNativeBoolean(Snapshot, value)); if (result != null) { break; } result = BitwiseOperation.Bitwise(OutSet, operation, TypeConversion.ToNativeInteger(Snapshot, leftOperand), TypeConversion.ToNativeInteger(Snapshot, value)); if (result != null) { break; } base.VisitAssociativeArray(value); break; } }
/// <inheritdoc /> public override void VisitFloatValue(FloatValue value) { switch (operation) { case Operations.Mod: // When dividend is true and divisor != +-1, result is 1, otherwise 0 result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand.Value), value.Value); break; default: var rightBoolean = TypeConversion.ToBoolean(value.Value); result = Comparison.Compare(OutSet, operation, leftOperand.Value, rightBoolean); if (result != null) { break; } var leftInteger = TypeConversion.ToInteger(leftOperand.Value); result = ArithmeticOperation.Arithmetic(flow, operation, leftInteger, value.Value); if (result != null) { break; } result = LogicalOperation.Logical(OutSet, operation, leftOperand.Value, rightBoolean); if (result != null) { break; } result = BitwiseOperation.Bitwise(OutSet, operation, leftInteger, value.Value); if (result != null) { break; } base.VisitFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitIntervalFloatValue(FloatIntervalValue value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToNativeInteger(Snapshot, leftOperand), value); break; default: result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToNativeBoolean(Snapshot, leftOperand), value); if (result != null) { break; } base.VisitIntervalFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitIntervalFloatValue(FloatIntervalValue value) { switch (operation) { case Operations.Identical: result = Comparison.Equal(OutSet, leftOperand.Value, value); break; case Operations.NotIdentical: result = Comparison.NotEqual(OutSet, leftOperand.Value, value); break; case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand.Value, value); break; default: result = Comparison.IntervalCompare(OutSet, operation, leftOperand.Value, value); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand.Value, value); if (result != null) { break; } result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToBoolean(leftOperand.Value), value); if (result != null) { break; } base.VisitIntervalFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitFloatValue(FloatValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.Equal: case Operations.GreaterThanOrEqual: result = OutSet.CreateBool(!TypeConversion.ToBoolean(value.Value)); break; case Operations.NotEqual: case Operations.LessThan: case Operations.Or: case Operations.Xor: result = TypeConversion.ToBoolean(OutSet, value); break; case Operations.Add: result = OutSet.CreateDouble(value.Value); break; case Operations.Sub: result = OutSet.CreateDouble(-value.Value); break; case Operations.Mul: result = OutSet.CreateDouble(0.0); break; case Operations.BitOr: case Operations.BitXor: int rightInteger; if (TypeConversion.TryConvertToInteger(value.Value, out rightInteger)) { result = OutSet.CreateInt(rightInteger); } else { result = OutSet.AnyIntegerValue; } break; case Operations.Div: if (value.Value != 0.0) { // 0 (null) divided or modulo by anything is always 0 result = OutSet.CreateDouble(0.0); } else { SetWarning("Division by floating-point zero", AnalysisWarningCause.DIVISION_BY_ZERO); // Division by floating-point zero does not return NaN // or infinite, but false boolean value result = OutSet.CreateBool(false); } break; case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand), value.Value); break; default: base.VisitFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitStringValue(StringValue value) { switch (operation) { case Operations.Identical: result = OutSet.CreateBool(string.Equals(leftOperand.Value, value.Value, StringComparison.Ordinal)); break; case Operations.NotIdentical: result = OutSet.CreateBool(!string.Equals(leftOperand.Value, value.Value, StringComparison.Ordinal)); break; case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand.Value, value.Value); break; case Operations.BitAnd: case Operations.BitOr: case Operations.BitXor: // Bit operations are defined for every character, not for the entire string // TODO: PHP string is stored as array of bytes, but printed in UTF8 encoding result = OutSet.AnyStringValue; break; default: result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToBoolean(leftOperand.Value), TypeConversion.ToBoolean(value.Value)); if (result != null) { break; } int leftInteger; double leftFloat; bool isLeftInteger; bool isLeftHexadecimal; var isLeftSuccessful = TypeConversion.TryConvertToNumber(leftOperand.Value, true, out leftInteger, out leftFloat, out isLeftInteger, out isLeftHexadecimal); int rightInteger; double rightFloat; bool isRightInteger; bool isRightHexadecimal; var isRightSuccessful = TypeConversion.TryConvertToNumber(value.Value, true, out rightInteger, out rightFloat, out isRightInteger, out isRightHexadecimal); // If both strings are convertible to number, they are conpared as numbers result = (isLeftSuccessful && isRightSuccessful) ? ((isLeftInteger && isRightInteger) ? Comparison.Compare(OutSet, operation, leftInteger, rightInteger) : Comparison.Compare(OutSet, operation, leftFloat, rightFloat)) : Comparison.Compare(OutSet, operation, leftOperand.Value, value.Value); if (result != null) { break; } result = (isLeftInteger && isRightInteger) ? ArithmeticOperation.Arithmetic(flow, operation, leftInteger, rightInteger) : ArithmeticOperation.Arithmetic(flow, operation, leftFloat, rightFloat); if (result != null) { break; } // If string has hexadecimal format, the first zero is recognized. if (isLeftHexadecimal) { leftInteger = 0; } if (isRightHexadecimal) { rightInteger = 0; } // Only shifting operations can happen if ((isLeftInteger || (isLeftSuccessful && TypeConversion.TryConvertToInteger(leftFloat, out leftInteger))) && (isRightInteger || (isRightSuccessful && TypeConversion.TryConvertToInteger(rightFloat, out rightInteger)))) { result = BitwiseOperation.Bitwise(OutSet, operation, leftInteger, rightInteger); if (result != null) { break; } } else { // If at least one operand can not be recognized, result can be any integer value. result = BitwiseOperation.Bitwise(OutSet, operation); if (result != null) { break; } } base.VisitStringValue(value); break; } }
/// <inheritdoc /> public override void VisitStringValue(StringValue value) { int integerValue; switch (operation) { case Operations.Identical: result = OutSet.CreateBool(false); break; case Operations.NotIdentical: result = OutSet.CreateBool(true); break; case Operations.Mod: // When dividend is true and divisor != +-1, result is 1, otherwise 0 result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand.Value), value.Value); break; default: var rightBoolean = TypeConversion.ToBoolean(value.Value); result = Comparison.Compare(OutSet, operation, leftOperand.Value, rightBoolean); if (result != null) { break; } result = LogicalOperation.Logical(OutSet, operation, leftOperand.Value, rightBoolean); if (result != null) { break; } var leftInteger = TypeConversion.ToInteger(leftOperand.Value); double floatValue; bool isInteger; bool isHexadecimal; var isSuccessful = TypeConversion.TryConvertToNumber(value.Value, true, out integerValue, out floatValue, out isInteger, out isHexadecimal); result = isInteger ? ArithmeticOperation.Arithmetic(flow, operation, leftInteger, integerValue) : ArithmeticOperation.Arithmetic(flow, operation, leftInteger, floatValue); if (result != null) { break; } // If string has hexadecimal format, the first zero is recognized. if (isHexadecimal) { integerValue = 0; } if (isInteger || (isSuccessful && TypeConversion.TryConvertToInteger(floatValue, out integerValue))) { result = BitwiseOperation.Bitwise(OutSet, operation, leftInteger, integerValue); if (result != null) { break; } } else { // If the right operand can not be recognized, result can be any integer value. result = BitwiseOperation.Bitwise(OutSet, operation); if (result != null) { break; } } base.VisitStringValue(value); break; } }
/// <inheritdoc /> public override void VisitStringValue(StringValue value) { switch (operation) { case Operations.Mod: result = ModuloOperation.Modulo(flow, leftOperand.Value, value.Value); break; default: result = LogicalOperation.Logical(OutSet, operation, TypeConversion.ToBoolean(leftOperand.Value), TypeConversion.ToBoolean(value.Value)); if (result != null) { break; } int integerValue; double floatValue; bool isInteger; bool isHexadecimal; var isSuccessful = TypeConversion.TryConvertToNumber(value.Value, true, out integerValue, out floatValue, out isInteger, out isHexadecimal); if (isInteger) { result = Comparison.Compare(OutSet, operation, leftOperand.Value, integerValue); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand.Value, integerValue); if (result != null) { break; } } else { result = Comparison.Compare(OutSet, operation, leftOperand.Value, floatValue); if (result != null) { break; } result = ArithmeticOperation.Arithmetic(flow, operation, leftOperand.Value, floatValue); if (result != null) { break; } } // If string has hexadecimal format, the first zero is recognized. if (isHexadecimal) { integerValue = 0; } if (isInteger || (isSuccessful && TypeConversion.TryConvertToInteger(floatValue, out integerValue))) { result = BitwiseOperation.Bitwise(OutSet, operation, leftOperand.Value, integerValue); if (result != null) { break; } } else { // If the right operand can not be recognized, result can be any integer value. result = BitwiseOperation.Bitwise(OutSet, operation); if (result != null) { break; } } base.VisitStringValue(value); break; } }