From b2d156d875e98b77abc42090b3a3c533414712b0 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Tue, 8 Jun 2021 13:32:36 +0200 Subject: [PATCH 1/2] Escape JDBC styled parameters. --- .../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 5cca2d2bf9..a54030589e 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 @@ * @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 d5db6d4dcc..a757fda895 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 @@ -34,6 +34,7 @@ * @author Oliver Gierke * @author Jens Schauder * @author Mark Paluch + * @author Michael J. Simons */ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) @@ -66,7 +67,7 @@ void renderAliasInExpressionQueryCorrectly() { 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})", @@ -75,4 +76,17 @@ void shouldDetectBindParameterCountCorrectly() { 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); + } + } From 7a5ed01c2d175210cb3abe3ad4e09108733957b7 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Tue, 8 Jun 2021 13:37:21 +0200 Subject: [PATCH 2/2] Polishing. --- .../data/jpa/repository/query/ExpressionBasedStringQuery.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 a54030589e..b907fdbf47 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 @@ -42,8 +42,8 @@ class ExpressionBasedStringQuery extends StringQuery { 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("([:\\?])#\\{"); - private static final Pattern EXPRESSION_PARAMETER_UNQUOTING = Pattern.compile("([:\\?])__HASH__\\{"); + 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;