From b2756f5bd2075138ee03f64946bdc391f85b6647 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 25 Dec 2018 13:22:00 +0100 Subject: [PATCH] Relaxed position assertion (for overflows in large inline maps) Issue: SPR-17605 --- .../expression/spel/ast/Assign.java | 10 +++--- .../expression/spel/ast/SpelNodeImpl.java | 35 +++++++++---------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.java index 4b0398760a..3289c66f5b 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ import org.springframework.expression.TypedValue; import org.springframework.expression.spel.ExpressionState; /** - * Represents assignment. An alternative to calling setValue() for an expression is to use - * an assign. + * Represents assignment. An alternative to calling {@code setValue} + * for an expression which indicates an assign statement. * *

Example: 'someNumberProperty=42' * @@ -31,8 +31,8 @@ import org.springframework.expression.spel.ExpressionState; */ public class Assign extends SpelNodeImpl { - public Assign(int pos,SpelNodeImpl... operands) { - super(pos,operands); + public Assign(int pos, SpelNodeImpl... operands) { + super(pos, operands); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java index aed04c557f..0cebe56449 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java @@ -47,7 +47,7 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { private static final SpelNodeImpl[] NO_CHILDREN = new SpelNodeImpl[0]; - protected int pos; // start = top 16bits, end = bottom 16bits + protected final int pos; // start = top 16bits, end = bottom 16bits protected SpelNodeImpl[] children = SpelNodeImpl.NO_CHILDREN; @@ -69,8 +69,6 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { public SpelNodeImpl(int pos, SpelNodeImpl... operands) { this.pos = pos; - // pos combines start and end so can never be zero because tokens cannot be zero length - Assert.isTrue(pos != 0, "Pos must not be 0"); if (!ObjectUtils.isEmpty(operands)) { this.children = operands; for (SpelNodeImpl operand : operands) { @@ -84,7 +82,7 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { /** * Return {@code true} if the next child is one of the specified classes. */ - protected boolean nextChildIs(Class... clazzes) { + protected boolean nextChildIs(Class... classes) { if (this.parent != null) { SpelNodeImpl[] peers = this.parent.children; for (int i = 0, max = peers.length; i < max; i++) { @@ -92,9 +90,9 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { if (i + 1 >= max) { return false; } - Class clazz = peers[i + 1].getClass(); - for (Class desiredClazz : clazzes) { - if (clazz.equals(desiredClazz)) { + Class peerClass = peers[i + 1].getClass(); + for (Class desiredClass : classes) { + if (peerClass == desiredClass) { return true; } } @@ -146,11 +144,6 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { return (obj instanceof Class ? ((Class) obj) : obj.getClass()); } - @Nullable - protected final T getValue(ExpressionState state, Class desiredReturnType) throws EvaluationException { - return ExpressionUtils.convertTypedValue(state.getEvaluationContext(), getValueInternal(state), desiredReturnType); - } - @Override public int getStartPosition() { return (this.pos >> 16); @@ -161,10 +154,6 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { return (this.pos & 0xffff); } - protected ValueRef getValueRef(ExpressionState state) throws EvaluationException { - throw new SpelEvaluationException(this.pos, SpelMessage.NOT_ASSIGNABLE, toStringAST()); - } - /** * Check whether a node can be compiled to bytecode. The reasoning in each node may * be different but will typically involve checking whether the exit type descriptor @@ -177,9 +166,8 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { /** * Generate the bytecode for this node into the supplied visitor. Context info about - * the current expression being compiled is available in the codeflow object. For - * example it will include information about the type of the object currently - * on the stack. + * the current expression being compiled is available in the codeflow object, e.g. + * including information about the type of the object currently on the stack. * @param mv the ASM MethodVisitor into which code should be generated * @param cf a context object with info about what is on the stack */ @@ -192,6 +180,15 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes { return this.exitTypeDescriptor; } + @Nullable + protected final T getValue(ExpressionState state, Class desiredReturnType) throws EvaluationException { + return ExpressionUtils.convertTypedValue(state.getEvaluationContext(), getValueInternal(state), desiredReturnType); + } + + protected ValueRef getValueRef(ExpressionState state) throws EvaluationException { + throw new SpelEvaluationException(getStartPosition(), SpelMessage.NOT_ASSIGNABLE, toStringAST()); + } + public abstract TypedValue getValueInternal(ExpressionState expressionState) throws EvaluationException; -- GitLab