diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java b/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java index 67b30b497b..71078aa340 100644 --- a/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java @@ -72,12 +72,15 @@ public static OMElement serializePath(SynapsePath path, String expression, elem.addAttribute(elem.getOMFactory().createOMAttribute( attribName, nullNS, expression)); } else if (path.getPathType() == SynapsePath.SYNAPSE_EXPRESSIONS_PATH) { - if (expression.startsWith("{") && expression.endsWith("}")) { + if (expression.startsWith("{${") && expression.endsWith("}}")) { elem.addAttribute(elem.getOMFactory().createOMAttribute( attribName, nullNS, expression)); + } else if (expression.startsWith("{") && expression.endsWith("}")) { + elem.addAttribute(elem.getOMFactory().createOMAttribute( + attribName, nullNS, "{${" + expression.substring(1, expression.length() - 1) + "}}")); } else { elem.addAttribute(elem.getOMFactory().createOMAttribute( - attribName, nullNS, "{" + expression + "}")); + attribName, nullNS, "{${" + expression + "}")); } } diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/BinaryOperationNode.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/BinaryOperationNode.java index 245de0e90b..6dfebbbeb3 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/BinaryOperationNode.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/BinaryOperationNode.java @@ -20,6 +20,7 @@ import org.apache.synapse.util.synapse.expression.context.EvaluationContext; import org.apache.synapse.util.synapse.expression.exception.EvaluationException; +import java.math.BigDecimal; import java.util.function.BiFunction; /** @@ -149,10 +150,23 @@ private ExpressionResult handleLogical(ExpressionResult leftValue, ExpressionRes } private ExpressionResult handleAddition(ExpressionResult leftValue, ExpressionResult rightValue) { - if (leftValue.isDouble() || rightValue.isDouble()) { - return new ExpressionResult(leftValue.asDouble() + rightValue.asDouble()); - } else if (leftValue.isInteger() && rightValue.isInteger()) { - return new ExpressionResult(leftValue.asInt() + rightValue.asInt()); + if (leftValue.isNumeric() && rightValue.isNumeric()) { + if (leftValue.isDouble() || rightValue.isDouble()) { + BigDecimal left = new BigDecimal(leftValue.asString()); + BigDecimal right = new BigDecimal(rightValue.asString()); + BigDecimal sum = left.add(right); + return new ExpressionResult(sum.doubleValue()); + } else if (leftValue.isLong() || rightValue.isLong()) { + return new ExpressionResult(leftValue.asLong() + rightValue.asLong()); + } else { + try { + int result = Math.addExact(leftValue.asInt(), rightValue.asInt()); + return new ExpressionResult(result); + } catch (ArithmeticException e) { + // handle overflow + return new ExpressionResult(leftValue.asLong() + rightValue.asLong()); + } + } } else if (leftValue.isString() && rightValue.isString()) { return new ExpressionResult(leftValue.asString().concat(rightValue.asString())); } @@ -166,23 +180,109 @@ private ExpressionResult handleArithmetic(ExpressionResult leftValue, Expression throw new EvaluationException("Arithmetic operation: " + operator + " between non-numeric values: " + leftValue.asString() + " and " + rightValue.asString()); } - boolean isInteger = leftValue.isInteger() && rightValue.isInteger(); + boolean leftIsDouble = leftValue.isDouble(); + boolean leftIsLong = leftValue.isLong(); + boolean rightIsDouble = rightValue.isDouble(); + boolean rightIsLong = rightValue.isLong(); + + // Promote to the highest precision type + if (leftIsDouble || rightIsDouble) { + double left = leftValue.asDouble(); + double right = rightValue.asDouble(); + return performDoubleOperation(left, right, operator); + } else if (leftIsLong || rightIsLong) { + long left = leftValue.asLong(); + long right = rightValue.asLong(); + return performLongOperation(left, right, operator); + } else { + // Default to int + int left = leftValue.asInt(); + int right = rightValue.asInt(); + return performIntOperation(left, right, operator); + } + } + + private ExpressionResult performDoubleOperation(double left, double right, Operator operator) { + BigDecimal left1 = new BigDecimal(String.valueOf(left)); + BigDecimal right1 = new BigDecimal(String.valueOf(right)); switch (operator) { case SUBTRACT: - return isInteger ? new ExpressionResult(leftValue.asInt() - rightValue.asInt()) : - new ExpressionResult(leftValue.asDouble() - rightValue.asDouble()); + BigDecimal sum = left1.subtract(right1); + return new ExpressionResult(sum.doubleValue()); case MULTIPLY: - return isInteger ? new ExpressionResult(leftValue.asInt() * rightValue.asInt()) : - new ExpressionResult(leftValue.asDouble() * rightValue.asDouble()); + BigDecimal product = left1.multiply(right1); + return new ExpressionResult(product.doubleValue()); case DIVIDE: - return isInteger ? new ExpressionResult(leftValue.asInt() / rightValue.asInt()) : - new ExpressionResult(leftValue.asDouble() / rightValue.asDouble()); + if (right == 0) { + throw new EvaluationException("Division by zero"); + } + BigDecimal quotient = left1.divide(right1, BigDecimal.ROUND_HALF_UP); + return new ExpressionResult(quotient.doubleValue()); case MODULO: - return isInteger ? new ExpressionResult(leftValue.asInt() % rightValue.asInt()) : - new ExpressionResult(leftValue.asDouble() % rightValue.asDouble()); + if (right == 0) { + throw new EvaluationException("Modulo by zero"); + } + BigDecimal remainder = left1.remainder(right1); + return new ExpressionResult(remainder.doubleValue()); default: throw new EvaluationException("Unsupported operator: " + operator + " between " - + leftValue.asString() + " and " + rightValue.asString()); + + left + " and " + right); + } + } + + private ExpressionResult performLongOperation(long left, long right, Operator operator) { + switch (operator) { + case SUBTRACT: + return new ExpressionResult(left - right); + case MULTIPLY: + return new ExpressionResult(left * right); + case DIVIDE: + if (right == 0L) { + throw new EvaluationException("Division by zero"); + } + return new ExpressionResult((double) left / right); + case MODULO: + if (right == 0L) { + throw new EvaluationException("Modulo by zero"); + } + return new ExpressionResult(left % right); + default: + throw new EvaluationException("Unsupported operator: " + operator + " between " + + left + " and " + right); + } + } + + private ExpressionResult performIntOperation(int left, int right, Operator operator) { + switch (operator) { + case SUBTRACT: + return new ExpressionResult(left - right); + case MULTIPLY: + try { + int result = Math.multiplyExact(left, right); + return new ExpressionResult(result); + } catch (ArithmeticException e) { + // handle overflow + return new ExpressionResult((long) left * (long) right); + } + case DIVIDE: + if (right == 0) { + throw new EvaluationException("Division by zero"); + } + if (left % right == 0) { + // Exact division, return as integer + return new ExpressionResult(left / right); + } else { + // Division has a fractional part, return as double + return new ExpressionResult((double) left / right); + } + case MODULO: + if (right == 0) { + throw new EvaluationException("Modulo by zero"); + } + return new ExpressionResult(left % right); + default: + throw new EvaluationException("Unsupported operator: " + operator + " between " + + left + " and " + right); } } } diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/ExpressionResult.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/ExpressionResult.java index 7c292abfb6..61255ddc6b 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/ExpressionResult.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/ExpressionResult.java @@ -29,7 +29,6 @@ import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.synapse.util.synapse.expression.exception.EvaluationException; - import java.util.List; /** @@ -67,7 +66,7 @@ public ExpressionResult(int value) { this.value = value; } - public ExpressionResult(Long value) { + public ExpressionResult(long value) { this.value = value; } @@ -180,13 +179,17 @@ public Class getType() { } public boolean isNumeric() { - return isInteger() || isDouble(); + return isInteger() || isDouble() || isLong(); } public boolean isInteger() { return value instanceof Integer || (value instanceof JsonPrimitive && isInteger((JsonPrimitive) value)); } + public boolean isLong() { + return value instanceof Long || (value instanceof JsonPrimitive && isLong((JsonPrimitive) value)); + } + public boolean isDouble() { return value instanceof Double || (value instanceof JsonPrimitive && isDouble((JsonPrimitive) value)); } @@ -235,8 +238,10 @@ private boolean isInteger(JsonPrimitive jsonPrimitive) { if (jsonPrimitive.isNumber()) { Number number = jsonPrimitive.getAsNumber(); // Check if the number is an instance of integer types (int, long, short) - boolean initialCheck = number instanceof Integer || number instanceof Long || number instanceof Short; - if (!initialCheck && number instanceof LazilyParsedNumber) { + if (number instanceof Long && number.longValue() <= Integer.MAX_VALUE) { + return true; + } + if (number instanceof LazilyParsedNumber) { // Check if the number is an instance of integer types (int, long, short) String numberString = number.toString(); try { @@ -246,17 +251,36 @@ private boolean isInteger(JsonPrimitive jsonPrimitive) { return false; } } - return initialCheck; } - return false; // Not a number, so it's not an integer + return false; + } + + private boolean isLong(JsonPrimitive jsonPrimitive) { + if (jsonPrimitive.isNumber()) { + Number number = jsonPrimitive.getAsNumber(); + // Check if the number is an instance of integer types (int, long, short) + if (number instanceof Long && number.longValue() > Integer.MAX_VALUE) { + return true; + } + if (number instanceof LazilyParsedNumber) { + // Check if the number is an instance of integer types (int, long, short) + String numberString = number.toString(); + try { + Long.parseLong(numberString); + return true; + } catch (NumberFormatException e) { + return false; + } + } + } + return false; } private boolean isDouble(JsonPrimitive jsonPrimitive) { if (jsonPrimitive.isNumber()) { Number number = jsonPrimitive.getAsNumber(); // Check if the number is an instance of floating-point types (float, double) - boolean initialCheck = number instanceof Float || number instanceof Double; - if (initialCheck) { + if (number instanceof Float || number instanceof Double) { return true; } if (number instanceof LazilyParsedNumber) { @@ -270,7 +294,7 @@ private boolean isDouble(JsonPrimitive jsonPrimitive) { } } } - return false; // Not a number, so it's not a double + return false; } public boolean isOMElement() { diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/LiteralNode.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/LiteralNode.java index 2ecad0c3da..ba82e5aba0 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/LiteralNode.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/LiteralNode.java @@ -72,7 +72,7 @@ private ExpressionResult parseNumber(String value) { return new ExpressionResult(Integer.parseInt(value)); } catch (NumberFormatException e1) { try { - return new ExpressionResult(Float.parseFloat(value)); + return new ExpressionResult(Long.parseLong(value)); } catch (NumberFormatException e2) { try { return new ExpressionResult(Double.parseDouble(value)); diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/PredefinedFunctionNode.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/PredefinedFunctionNode.java index 416096d0ab..e2cea240d3 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/PredefinedFunctionNode.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/PredefinedFunctionNode.java @@ -177,6 +177,8 @@ private ExpressionResult handleDoubleArgumentFunctions(EvaluationContext context return handleCharAtFunction(source, argument1); case ExpressionConstants.XPATH: return evaluateXPATHExpression(context, source, argument1.asString(), isObjectValue); + case ExpressionConstants.ROUND: + return handleRoundFunction(source, argument1); default: throw new EvaluationException("Invalid function: " + functionName + " with two arguments"); } @@ -279,6 +281,15 @@ private ExpressionResult handleRoundFunction(ExpressionResult result) { throw new EvaluationException("Invalid argument provided for round function"); } + private ExpressionResult handleRoundFunction(ExpressionResult result, ExpressionResult decimalPlaces) { + if (result.isDouble() && decimalPlaces.isInteger() && decimalPlaces.asInt() > 0) { + return new ExpressionResult(ExpressionUtils.round(result.asDouble(), decimalPlaces.asInt())); + } else if (result.isInteger() || result.isLong()) { + return result; + } + throw new EvaluationException("Invalid argument provided for round function"); + } + private ExpressionResult handleSqrtFunction(ExpressionResult result) { if (result.isInteger()) { return new ExpressionResult(Math.sqrt(result.asInt())); diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/utils/ExpressionUtils.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/utils/ExpressionUtils.java index ff8076b5e9..66ca579ede 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/utils/ExpressionUtils.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/utils/ExpressionUtils.java @@ -19,6 +19,9 @@ package org.apache.synapse.util.synapse.expression.utils; import org.apache.axiom.om.OMNode; + +import java.math.BigDecimal; +import java.math.RoundingMode; import java.nio.charset.Charset; import java.util.List; @@ -112,4 +115,16 @@ public static boolean isXMLVariable(Object variable) { } return isXML; } + + /** + * Rounds the given value to the specified number of decimal places. + * @param value The value to be rounded. + * @param decimalPlaces The number of decimal places to round to. + * @return The rounded value. + */ + public static Double round (double value, int decimalPlaces) { + BigDecimal bd = new BigDecimal(Double.toString(value)); + bd = bd.setScale(decimalPlaces, RoundingMode.HALF_UP); + return bd.doubleValue(); + } } diff --git a/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java b/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java index 8ee16b8dc0..d7d835dcf8 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java +++ b/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java @@ -21,6 +21,7 @@ import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -63,6 +64,11 @@ public SynapseExpression(String synapseExpression) throws JaxenException { parser.addErrorListener(errorListener); ParseTree tree = parser.expression(); + // if there are any tokens left after parsing the expression, throw an exception + if (tokens.LA(1) != Token.EOF) { + throw new JaxenException("Parse error: leftover input after parsing expression in " + synapseExpression); + } + ExpressionVisitor visitor = new ExpressionVisitor(); expressionNode = visitor.visit(tree); if (errorListener.hasErrors()) { @@ -73,6 +79,7 @@ public SynapseExpression(String synapseExpression) throws JaxenException { throw new JaxenException(errorMessage.toString()); } isContentAware = SynapseExpressionUtils.isSynapseExpressionContentAware(synapseExpression); + this.setPathType(SynapsePath.SYNAPSE_EXPRESSIONS_PATH); } @Override diff --git a/modules/core/src/test/java/org/apache/synapse/config/xml/ThrowErrorMediatorSerializerTest.java b/modules/core/src/test/java/org/apache/synapse/config/xml/ThrowErrorMediatorSerializerTest.java index a2dcce68c2..2ada9d4a34 100644 --- a/modules/core/src/test/java/org/apache/synapse/config/xml/ThrowErrorMediatorSerializerTest.java +++ b/modules/core/src/test/java/org/apache/synapse/config/xml/ThrowErrorMediatorSerializerTest.java @@ -24,7 +24,7 @@ public void testSerializeThrowErrorMediator() throws JaxenException { OMElement element = throwErrorMediatorSerializer.serializeSpecificMediator(mediator); Assert.assertEquals("invalid type", type, element.getAttributeValue(new QName("type"))); Assert.assertEquals("invalid error message", err, element.getAttributeValue(new QName("errorMessage"))); - mediator.setErrorMsg(new Value(new SynapseExpression(exp))); + mediator.setErrorMsg(new Value(new SynapseExpression("payload.err"))); element = throwErrorMediatorSerializer.serializeSpecificMediator(mediator); Assert.assertEquals("invalid error message", "{" + exp + "}", element.getAttributeValue(new QName("errorMessage"))); } diff --git a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/ContentAwarenessTest.java b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/ContentAwarenessTest.java index b968f5695f..17156476f9 100644 --- a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/ContentAwarenessTest.java +++ b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/ContentAwarenessTest.java @@ -65,7 +65,7 @@ public void testWithXpath() throws JaxenException { Assert.assertTrue(synapsePath.isContentAware()); synapsePath = new SynapseExpression("xpath(\"/student\")"); Assert.assertTrue(synapsePath.isContentAware()); - synapsePath = new SynapseExpression("xpath(\"//*\") + vars.a$bc"); + synapsePath = new SynapseExpression("xpath(\"//*\") + vars.abc"); Assert.assertTrue(synapsePath.isContentAware()); synapsePath = new SynapseExpression("xpath(\"$ctx:bla\") + $.age"); Assert.assertTrue(synapsePath.isContentAware()); @@ -81,9 +81,9 @@ public void testNegativeCases() throws JaxenException { Assert.assertFalse(synapsePath.isContentAware()); synapsePath = new SynapseExpression("vars[\"payload\"]"); Assert.assertFalse(synapsePath.isContentAware()); - synapsePath = new SynapseExpression("5 + var[\"payload\"].age"); + synapsePath = new SynapseExpression("5 + vars[\"payload\"].age"); Assert.assertFalse(synapsePath.isContentAware()); - synapsePath = new SynapseExpression("vars.a$.bc"); + synapsePath = new SynapseExpression("vars.a.bc"); Assert.assertFalse(synapsePath.isContentAware()); synapsePath = new SynapseExpression("vars.books[?(@.category==\"payload.category\")]"); Assert.assertFalse(synapsePath.isContentAware()); diff --git a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PreDefinedFunctionsTest.java b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PreDefinedFunctionsTest.java index 149644e5e2..42e4f7c0dc 100644 --- a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PreDefinedFunctionsTest.java +++ b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PreDefinedFunctionsTest.java @@ -355,6 +355,15 @@ public void testRound() { Assert.assertEquals("15", TestUtils.evaluateExpressionWithPayloadAndVariables( "round(vars.num1 + vars.num2)", 0, 1)); Assert. assertEquals("", TestUtils.evaluateExpressionWithPayload("round(payload)", 3)); + Assert. assertEquals("", TestUtils.evaluateExpressionWithPayload("round(payload)", 3)); + Assert.assertEquals("9.0", TestUtils.evaluateExpression("round(8.89 + 0.12,1)")); + Assert.assertEquals("9.01", TestUtils.evaluateExpression("round(8.89 + 0.12,2)")); + Assert.assertEquals("0.11", TestUtils.evaluateExpression("round(0.111,2)")); + Assert.assertEquals("0.12", TestUtils.evaluateExpression("round(0.115,2)")); + Assert.assertEquals("0.111", TestUtils.evaluateExpression("round(0.111,3)")); + Assert.assertEquals("0.111", TestUtils.evaluateExpression("round(0.111,4)")); + Assert.assertEquals("", TestUtils.evaluateExpression("round(0.111,0)")); + Assert.assertEquals("", TestUtils.evaluateExpression("round(0.111,\"asdf\")")); } @Test diff --git a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PrimitiveExpressionsTest.java b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PrimitiveExpressionsTest.java index 1717d844eb..dd5dace589 100644 --- a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PrimitiveExpressionsTest.java +++ b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/PrimitiveExpressionsTest.java @@ -112,6 +112,7 @@ public void testOr() { @Test public void testAdd() { + Assert.assertEquals("17.94", TestUtils.evaluateExpression("8.95 + 8.99")); Assert.assertEquals("8.5", TestUtils.evaluateExpression("5.5 + 3")); Assert.assertEquals("7", TestUtils.evaluateExpression("5 + 3 + -1")); Assert.assertEquals("8.5", TestUtils.evaluateExpression("5.5 + 3")); @@ -125,10 +126,14 @@ public void testAdd() { Assert.assertEquals("", TestUtils.evaluateExpressionWithPayloadAndVariables("5 + vars.name", 2, 1)); // clear the synCtx to remove previous payload and variables. Assert.assertEquals("", TestUtils.evaluateExpression("vars.num99 + 5")); + // Integer type overflow test + Assert.assertEquals("2147483648", TestUtils.evaluateExpression("2147483647 + 1")); } @Test public void testSubtract() { + Assert.assertEquals("1000000", TestUtils.evaluateExpression("3148483647 - 3147483647")); + Assert.assertEquals("0.0111", TestUtils.evaluateExpression("8.9567 - 8.9456")); Assert.assertEquals("-33", TestUtils.evaluateExpression("5 - 30 + 2 - 10")); Assert.assertEquals("2.5", TestUtils.evaluateExpression("5.5 - 3")); Assert.assertEquals("2.0", TestUtils.evaluateExpression("5.5 - 3.5")); @@ -140,6 +145,9 @@ public void testSubtract() { @Test public void testMultiply() { + Assert.assertEquals("80.8201", TestUtils.evaluateExpression("8.99 * 8.99")); + Assert.assertEquals("26.25", TestUtils.evaluateExpression("25 * 1.05")); + Assert.assertEquals("25.025", TestUtils.evaluateExpression("25 * 1.001")); Assert.assertEquals("-30", TestUtils.evaluateExpression("5 * 3 * -2")); Assert.assertEquals("16.5", TestUtils.evaluateExpression("5.5 * 3")); Assert.assertEquals("19.25", TestUtils.evaluateExpression("5.5 * 3.5")); @@ -147,10 +155,14 @@ public void testMultiply() { Assert.assertEquals("", TestUtils.evaluateExpression("5 * \"bla\"")); Assert.assertEquals("-25.0", TestUtils.evaluateExpressionWithPayloadAndVariables( "vars.num1 * vars.num3", 2, 1)); + // Integer type overflow test + Assert.assertEquals("-4294967294", TestUtils.evaluateExpression("2147483647 * -2")); + Assert.assertEquals("4294927294", TestUtils.evaluateExpression("2147463647 * 2")); } @Test public void testDivide() { + Assert.assertEquals("10.01", TestUtils.evaluateExpression("34.45 / 3.44")); Assert.assertEquals("-4.0", TestUtils.evaluateExpression("10 / 2 / -2.5 * 2")); Assert.assertEquals("-4.0", TestUtils.evaluateExpression("10 / 2 / -2.5 * 2")); Assert.assertEquals("3", TestUtils.evaluateExpression("9 / 3")); @@ -158,10 +170,19 @@ public void testDivide() { Assert.assertEquals("", TestUtils.evaluateExpression("5 / \"bla\"")); Assert.assertEquals("5", TestUtils.evaluateExpressionWithPayloadAndVariables( "vars.num1 / 2", 2, 1)); + Assert.assertEquals("", TestUtils.evaluateExpression("5/0")); + Assert.assertEquals("", TestUtils.evaluateExpression("5.2/0")); + Assert.assertEquals("0.001", TestUtils.evaluateExpression("10/10000")); + Assert.assertEquals("", TestUtils.evaluateExpression("2147483650/0")); + Assert.assertEquals("0.5", TestUtils.evaluateExpression("5/10")); + Assert.assertEquals("2.0E9", TestUtils.evaluateExpression("20000000000/10")); + Assert.assertEquals("20000000", TestUtils.evaluateExpression("200000000/10")); + Assert.assertEquals("10.0", TestUtils.evaluateExpression("100/10.0")); } @Test public void testMod() { + Assert.assertEquals("0.06", TestUtils.evaluateExpression("34.56 % 3.45")); Assert.assertEquals("1", TestUtils.evaluateExpression("10 % 3")); Assert.assertEquals("2.5", TestUtils.evaluateExpression("5.5 % 3")); Assert.assertEquals("2.0", TestUtils.evaluateExpression("5.5 % 3.5")); diff --git a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/SyntaxErrorsTest.java b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/SyntaxErrorsTest.java index 10184ee364..4bef5b1e24 100644 --- a/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/SyntaxErrorsTest.java +++ b/modules/core/src/test/java/org/apache/synapse/util/synapse/expression/SyntaxErrorsTest.java @@ -52,4 +52,9 @@ public void testOperationError() { syntaxErrorListener.clearErrors(); } + + @Test (expected = RuntimeException.class) + public void testInvalidExpressionByLength() { + TestUtils.evaluateExpression("payload.products[0].stock + abc"); + } }