Browse Source

Ensure cast correctly included for OpPlus compilation

When the plus operator is used between strings in a SpEL
expression and that expression is compiled, it is
important to include a cast if computation of any of
the operands isn't obviously leaving strings on the
stack. Likewise if the stack contents are known to
be strings, a cast should not be included.

Issue: SPR-12426
pull/929/head
Andy Clement 9 years ago
parent
commit
58756b023c
  1. 2
      spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java
  2. 23
      spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java

2
spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java

@ -198,7 +198,7 @@ public class OpPlus extends Operator { @@ -198,7 +198,7 @@ public class OpPlus extends Operator {
else {
cf.enterCompilationScope();
operand.generateCode(mv,cf);
if (cf.lastDescriptor() != "Ljava/lang/String") {
if (!"Ljava/lang/String".equals(cf.lastDescriptor())) {
mv.visitTypeInsn(CHECKCAST, "java/lang/String");
}
cf.exitCompilationScope();

23
spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java

@ -4194,6 +4194,29 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests { @@ -4194,6 +4194,29 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
assertEquals("value1",stringify(expression.getValue(mapArray)));
assertEquals("Ljava/lang/Object",getAst().getExitDescriptor());
}
@Test
public void plusNeedingCheckcast_SPR12426() {
expression = parser.parseExpression("object + ' world'");
Object v = expression.getValue(new FooObject());
assertEquals("hello world",v);
assertCanCompile(expression);
assertEquals("hello world",v);
expression = parser.parseExpression("object + ' world'");
v = expression.getValue(new FooString());
assertEquals("hello world",v);
assertCanCompile(expression);
assertEquals("hello world",v);
}
public static class FooObject {
public Object getObject() { return "hello"; }
}
public static class FooString {
public String getObject() { return "hello"; }
}
@Test
public void mixingItUp_propertyAccessIndexerOpLtTernaryRootNull() throws Exception {

Loading…
Cancel
Save