From 085c771747fad6a8348ea0e47c65f9d5dd13f968 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Tue, 8 Jun 2021 13:32:36 +0200 Subject: [PATCH] Escape JDBC styled parameters. Closes #2228 Original pull request #2229 --- .../query/ExpressionBasedStringQuery.java | 10 +++++----- .../ExpressionBasedStringQueryUnitTests.java | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java index 5cca2d2bf..a54030589 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java @@ -35,15 +35,15 @@ import org.springframework.util.Assert; * @author Thomas Darimont * @author Oliver Gierke * @author Tom Hombergs + * @author Michael J. Simons */ class ExpressionBasedStringQuery extends StringQuery { - private static final String EXPRESSION_PARAMETER = "?#{"; - private static final String QUOTED_EXPRESSION_PARAMETER = "?__HASH__{"; + private static final String EXPRESSION_PARAMETER = "$1#{"; + private static final String QUOTED_EXPRESSION_PARAMETER = "$1__HASH__{"; - private static final Pattern EXPRESSION_PARAMETER_QUOTING = Pattern.compile(Pattern.quote(EXPRESSION_PARAMETER)); - private static final Pattern EXPRESSION_PARAMETER_UNQUOTING = Pattern.compile(Pattern - .quote(QUOTED_EXPRESSION_PARAMETER)); + private static final Pattern EXPRESSION_PARAMETER_QUOTING = Pattern.compile("([:\\?])#\\{"); + private static final Pattern EXPRESSION_PARAMETER_UNQUOTING = Pattern.compile("([:\\?])__HASH__\\{"); private static final String ENTITY_NAME = "entityName"; private static final String ENTITY_NAME_VARIABLE = "#" + ENTITY_NAME; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java index 6ffb0b019..6fadecba9 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java @@ -31,6 +31,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser; * @author Oliver Gierke * @author Jens Schauder * @author Mark Paluch + * @author Michael J. Simons */ @RunWith(MockitoJUnitRunner.class) public class ExpressionBasedStringQueryUnitTests { @@ -62,7 +63,7 @@ public class ExpressionBasedStringQueryUnitTests { public void shouldDetectBindParameterCountCorrectly() { StringQuery query = new ExpressionBasedStringQuery( - "select n from NetworkServer n where (LOWER(n.name) LIKE LOWER(NULLIF(text(concat('%',:#{#networkRequest.name},'%')), '')) OR :#{#networkRequest.name} IS NULL )\"\n" + "select n from #{#entityName} n where (LOWER(n.name) LIKE LOWER(NULLIF(text(concat('%',:#{#networkRequest.name},'%')), '')) OR :#{#networkRequest.name} IS NULL )\"\n" + "+ \"AND (LOWER(n.server) LIKE LOWER(NULLIF(text(concat('%',:#{#networkRequest.server},'%')), '')) OR :#{#networkRequest.server} IS NULL)\"\n" + "+ \"AND (n.createdAt >= :#{#networkRequest.createdTime.startDateTime}) AND (n.createdAt <=:#{#networkRequest.createdTime.endDateTime})\"\n" + "+ \"AND (n.updatedAt >= :#{#networkRequest.updatedTime.startDateTime}) AND (n.updatedAt <=:#{#networkRequest.updatedTime.endDateTime})", @@ -71,4 +72,17 @@ public class ExpressionBasedStringQueryUnitTests { assertThat(query.getParameterBindings()).hasSize(8); } + @Test // GH-2228 + void shouldDetectBindParameterCountCorrectlyWithJDBCStyleParameters() { + + StringQuery query = new ExpressionBasedStringQuery( + "select n from #{#entityName} n where (LOWER(n.name) LIKE LOWER(NULLIF(text(concat('%',?#{#networkRequest.name},'%')), '')) OR ?#{#networkRequest.name} IS NULL )\"\n" + + "+ \"AND (LOWER(n.server) LIKE LOWER(NULLIF(text(concat('%',?#{#networkRequest.server},'%')), '')) OR ?#{#networkRequest.server} IS NULL)\"\n" + + "+ \"AND (n.createdAt >= ?#{#networkRequest.createdTime.startDateTime}) AND (n.createdAt <=?#{#networkRequest.createdTime.endDateTime})\"\n" + + "+ \"AND (n.updatedAt >= ?#{#networkRequest.updatedTime.startDateTime}) AND (n.updatedAt <=?#{#networkRequest.updatedTime.endDateTime})", + metadata, SPEL_PARSER); + + assertThat(query.getParameterBindings()).hasSize(8); + } + }