From f44d13cb7816e586b86c02421af4f5498391111c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 18 Oct 2022 18:59:37 +0200 Subject: [PATCH] Disable array allocation in case of no constructor resolution See gh-28808 Closes gh-33386 (cherry picked from commit a3a48a241c6e611d37dcc0444979644ef9eb701e) --- .../spel/ast/ConstructorReference.java | 9 ++++++++- .../spel/ArrayConstructorTests.java | 20 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java index 137eacf8f5d0..286f51930e22 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -268,6 +268,13 @@ private TypedValue createArray(ExpressionState state) throws EvaluationException } String type = (String) intendedArrayType; + + if (state.getEvaluationContext().getConstructorResolvers().isEmpty()) { + // No constructor resolver -> no array construction either (as of 5.3.38) + throw new SpelEvaluationException(getStartPosition(), SpelMessage.CONSTRUCTOR_NOT_FOUND, + type + "[]", "[]"); + } + Class componentType; TypeCode arrayTypeCode = TypeCode.forName(type); if (arrayTypeCode == TypeCode.OBJECT) { diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/ArrayConstructorTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/ArrayConstructorTests.java index 252e532e748f..0fd3c394c380 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/ArrayConstructorTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/ArrayConstructorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -18,17 +18,21 @@ import org.junit.jupiter.api.Test; +import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.SimpleEvaluationContext; import org.springframework.util.ObjectUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** * Test construction of arrays. * * @author Andy Clement * @author Sam Brannen + * @author Juergen Hoeller */ class ArrayConstructorTests extends AbstractExpressionTests { @@ -97,7 +101,7 @@ void errorCases() { void typeArrayConstructors() { evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class); evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessage.METHOD_NOT_FOUND, 30, "size()", - "java.lang.String[]"); + "java.lang.String[]"); evaluate("new String[]{'a','b','c','d'}.length", 4, Integer.class); } @@ -110,10 +114,18 @@ void basicArray() { void multiDimensionalArrays() { evaluate("new String[2][2]", "[Ljava.lang.String;[2]{[2]{null,null},[2]{null,null}}", String[][].class); evaluate("new String[3][2][1]", - "[[Ljava.lang.String;[3]{[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}}}", - String[][][].class); + "[[Ljava.lang.String;[3]{[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}}}", + String[][][].class); } + @Test + void noArrayConstruction() { + EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); + assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() -> + parser.parseExpression("new int[2]").getValue(context)); + } + + private void evaluateArrayBuildingExpression(String expression, String expectedToString) { SpelExpressionParser parser = new SpelExpressionParser(); Expression e = parser.parseExpression(expression);