From 25733664b3d66bc0ee4c496ea286972f799d61cb Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 29 Jun 2020 11:18:45 +0200 Subject: [PATCH] DATAMONGO-2571 - Fix regular expression parameter binding for String-based queries. Original pull request: #873. --- .../util/json/ParameterBindingJsonReader.java | 19 +++++++++++++------ .../ParameterBindingJsonReaderUnitTests.java | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java index 77cd05747..b3f86aa7a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java @@ -229,7 +229,7 @@ public class ParameterBindingJsonReader extends AbstractBsonReader { case REGULAR_EXPRESSION: setCurrentBsonType(BsonType.REGULAR_EXPRESSION); - currentValue = bindableValueFor(token).getValue().toString(); + currentValue = bindableValueFor(token).getValue(); break; case STRING: @@ -365,8 +365,11 @@ public class ParameterBindingJsonReader extends AbstractBsonReader { return null; } + boolean isRegularExpression = token.getType().equals(JsonTokenType.REGULAR_EXPRESSION); + BindableValue bindableValue = new BindableValue(); - String tokenValue = String.class.cast(token.getValue()); + String tokenValue = isRegularExpression ? token.getValue(BsonRegularExpression.class).getPattern() + : String.class.cast(token.getValue()); Matcher matcher = PARAMETER_BINDING_PATTERN.matcher(tokenValue); if (token.getType().equals(JsonTokenType.UNQUOTED_STRING)) { @@ -406,8 +409,6 @@ public class ParameterBindingJsonReader extends AbstractBsonReader { String computedValue = tokenValue; - - Matcher regexMatcher = EXPRESSION_BINDING_PATTERN.matcher(computedValue); while (regexMatcher.find()) { @@ -437,9 +438,15 @@ public class ParameterBindingJsonReader extends AbstractBsonReader { computedValue = computedValue.replace(group, nullSafeToString(getBindableValueForIndex(index))); } - bindableValue.setValue(computedValue); - bindableValue.setType(BsonType.STRING); + if (isRegularExpression) { + bindableValue.setValue(new BsonRegularExpression(computedValue)); + bindableValue.setType(BsonType.REGULAR_EXPRESSION); + } else { + + bindableValue.setValue(computedValue); + bindableValue.setType(BsonType.STRING); + } return bindableValue; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java index 6939add04..a237a5434 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java @@ -333,6 +333,22 @@ class ParameterBindingJsonReaderUnitTests { new Document("user.supervisor", "wonderwoman")))); } + @Test // DATAMONGO-2571 + public void shouldParseRegexCorrectly() { + + Document target = parse("{ $and: [{'fieldA': {$in: [/ABC.*/, /CDE.*F/]}}, {'fieldB': {$ne: null}}]}"); + assertThat(target) + .isEqualTo(Document.parse("{ $and: [{'fieldA': {$in: [/ABC.*/, /CDE.*F/]}}, {'fieldB': {$ne: null}}]}")); + } + + @Test // DATAMONGO-2571 + public void shouldParseRegexWithPlaceholderCorrectly() { + + Document target = parse("{ $and: [{'fieldA': {$in: [/?0.*/, /CDE.*F/]}}, {'fieldB': {$ne: null}}]}", "ABC"); + assertThat(target) + .isEqualTo(Document.parse("{ $and: [{'fieldA': {$in: [/ABC.*/, /CDE.*F/]}}, {'fieldB': {$ne: null}}]}")); + } + private static Document parse(String json, Object... args) { ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);