Skip to content

Commit f4460dc

Browse files
committed
SPR-6059 Avoiding NPE for unary-not and ternary operators. If the value is null instead of a valid boolean or Boolean, it will now trigger an EvaluationException.
1 parent a2cd909 commit f4460dc

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorNot.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.expression.spel.ast;
1818

19+
import org.springframework.core.convert.TypeDescriptor;
1920
import org.springframework.expression.EvaluationException;
2021
import org.springframework.expression.spel.ExpressionState;
2122
import org.springframework.expression.spel.SpelEvaluationException;
@@ -36,7 +37,7 @@ public OperatorNot(int pos, SpelNodeImpl operand) {
3637
@Override
3738
public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
3839
try {
39-
boolean value = (Boolean)state.convertValue(children[0].getValueInternal(state), BOOLEAN_TYPE_DESCRIPTOR);
40+
boolean value = (Boolean) state.convertValue(children[0].getValueInternal(state), TypeDescriptor.valueOf(boolean.class));
4041
return BooleanTypedValue.forValue(!value);
4142
}
4243
catch (SpelEvaluationException see) {

org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Ternary.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import org.springframework.expression.EvaluationException;
2020
import org.springframework.expression.TypedValue;
2121
import org.springframework.expression.spel.ExpressionState;
22+
import org.springframework.expression.spel.SpelEvaluationException;
23+
import org.springframework.expression.spel.SpelMessage;
2224

2325
/**
2426
* Represents a ternary expression, for example: "someCheck()?true:false".
@@ -43,6 +45,10 @@ public Ternary(int pos, SpelNodeImpl... args) {
4345
@Override
4446
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
4547
Boolean value = children[0].getValue(state, Boolean.class);
48+
if (value == null) {
49+
throw new SpelEvaluationException(getChild(0).getStartPosition(),
50+
SpelMessage.TYPE_CONVERSION_ERROR, "null", "boolean");
51+
}
4652
if (value.booleanValue()) {
4753
return children[1].getValueInternal(state);
4854
} else {

org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
* Tests the evaluation of real expressions in a real context.
3737
*
3838
* @author Andy Clement
39+
* @author Mark Fisher
40+
* @since 3.0
3941
*/
4042
public class EvaluationTests extends ExpressionTestCase {
4143

@@ -296,6 +298,16 @@ public void testUnaryNot01() {
296298
evaluate("!true", "false", Boolean.class);
297299
}
298300

301+
@Test
302+
public void testUnaryNot02() {
303+
evaluate("!false", "true", Boolean.class);
304+
}
305+
306+
@Test(expected = EvaluationException.class)
307+
public void testUnaryNotWithNullValue() {
308+
parser.parseExpression("!null").getValue();
309+
}
310+
299311
// assignment
300312
@Test
301313
public void testAssignmentToVariables01() {
@@ -307,7 +319,6 @@ public void testTernaryOperator01() {
307319
evaluate("2>4?1:2",2,Integer.class);
308320
}
309321

310-
311322
@Test
312323
public void testTernaryOperator02() {
313324
evaluate("'abc'=='abc'?1:2",1,Integer.class);
@@ -332,6 +343,11 @@ public void testTernaryOperator05() {
332343
evaluate("2>4?(3>2?true:false):(5<3?true:false)",false,Boolean.class);
333344
}
334345

346+
@Test(expected = EvaluationException.class)
347+
public void testTernaryOperatorWithNullValue() {
348+
parser.parseExpression("null ? 0 : 1").getValue();
349+
}
350+
335351
@Test
336352
public void testIndexer03() {
337353
evaluate("'christian'[8]", "n", String.class);

0 commit comments

Comments
 (0)