Skip to content

Commit 079d53c

Browse files
committed
Support compilation of array and list indexing with Integer in SpEL
Prior to this commit, the Spring Expression Language (SpEL) failed to compile an expression that indexed into an array or list using an Integer. This commit adds support for compilation of such expressions by ensuring that an Integer is unboxed into an int in the compiled bytecode. See gh-32694 Closes gh-32908 (cherry picked from commit cda577d)
1 parent 206a890 commit 079d53c

File tree

2 files changed

+455
-11
lines changed

2 files changed

+455
-11
lines changed

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

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -225,6 +225,8 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
225225
cf.loadTarget(mv);
226226
}
227227

228+
SpelNodeImpl index = this.children[0];
229+
228230
if (this.indexedType == IndexedType.ARRAY) {
229231
int insn;
230232
if ("D".equals(this.exitTypeDescriptor)) {
@@ -261,32 +263,28 @@ else if ("C".equals(this.exitTypeDescriptor)) {
261263
//depthPlusOne(exitTypeDescriptor)+"Ljava/lang/Object;");
262264
insn = AALOAD;
263265
}
264-
SpelNodeImpl index = this.children[0];
265-
cf.enterCompilationScope();
266-
index.generateCode(mv, cf);
267-
cf.exitCompilationScope();
266+
267+
generateIndexCode(mv, cf, index, int.class);
268268
mv.visitInsn(insn);
269269
}
270270

271271
else if (this.indexedType == IndexedType.LIST) {
272272
mv.visitTypeInsn(CHECKCAST, "java/util/List");
273-
cf.enterCompilationScope();
274-
this.children[0].generateCode(mv, cf);
275-
cf.exitCompilationScope();
273+
generateIndexCode(mv, cf, index, int.class);
276274
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
277275
}
278276

279277
else if (this.indexedType == IndexedType.MAP) {
280278
mv.visitTypeInsn(CHECKCAST, "java/util/Map");
281279
// Special case when the key is an unquoted string literal that will be parsed as
282280
// a property/field reference
283-
if ((this.children[0] instanceof PropertyOrFieldReference reference)) {
281+
if (index instanceof PropertyOrFieldReference reference) {
284282
String mapKeyName = reference.getName();
285283
mv.visitLdcInsn(mapKeyName);
286284
}
287285
else {
288286
cf.enterCompilationScope();
289-
this.children[0].generateCode(mv, cf);
287+
index.generateCode(mv, cf);
290288
cf.exitCompilationScope();
291289
}
292290
mv.visitMethodInsn(
@@ -323,6 +321,11 @@ else if (this.indexedType == IndexedType.OBJECT) {
323321
cf.pushDescriptor(this.exitTypeDescriptor);
324322
}
325323

324+
private void generateIndexCode(MethodVisitor mv, CodeFlow cf, SpelNodeImpl indexNode, Class<?> indexType) {
325+
String indexDesc = CodeFlow.toDescriptor(indexType);
326+
generateCodeForArgument(mv, cf, indexNode, indexDesc);
327+
}
328+
326329
@Override
327330
public String toStringAST() {
328331
StringJoiner sj = new StringJoiner(",", "[", "]");

0 commit comments

Comments
 (0)