SqlIdentifierParameterSource now sanitizes identifier names.
Closes #1405 See #1406 Original pull request #1415
This commit is contained in:
committed by
Mark Paluch
parent
e2422c2a83
commit
eff0c72126
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.jdbc.core.convert;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Sanitizes the name of bind parameters, so they don't contain any illegal characters.
|
||||
*
|
||||
* @author Jens Schauder
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
enum BindParameterNameSanitizer {
|
||||
INSTANCE;
|
||||
|
||||
private static final Pattern parameterPattern = Pattern.compile("\\W");
|
||||
|
||||
String sanitize(String rawName) {
|
||||
|
||||
return parameterPattern.matcher(rawName).replaceAll("");
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,6 @@ class SqlGenerator {
|
||||
static final SqlIdentifier IDS_SQL_PARAMETER = SqlIdentifier.unquoted("ids");
|
||||
static final SqlIdentifier ROOT_ID_PARAMETER = SqlIdentifier.unquoted("rootId");
|
||||
|
||||
private static final Pattern parameterPattern = Pattern.compile("\\W");
|
||||
private final RelationalPersistentEntity<?> entity;
|
||||
private final MappingContext<RelationalPersistentEntity<?>, RelationalPersistentProperty> mappingContext;
|
||||
private final RenderContext renderContext;
|
||||
@@ -158,7 +157,7 @@ class SqlGenerator {
|
||||
}
|
||||
|
||||
private BindMarker getBindMarker(SqlIdentifier columnName) {
|
||||
return SQL.bindMarker(":" + parameterPattern.matcher(renderReference(columnName)).replaceAll(""));
|
||||
return SQL.bindMarker(":" + BindParameterNameSanitizer.INSTANCE.sanitize(renderReference(columnName)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -68,7 +68,7 @@ class SqlIdentifierParameterSource extends AbstractSqlParameterSource {
|
||||
void addValue(SqlIdentifier identifier, Object value, int sqlType) {
|
||||
|
||||
identifiers.add(identifier);
|
||||
String name = identifier.getReference(identifierProcessing);
|
||||
String name = BindParameterNameSanitizer.INSTANCE.sanitize(identifier.getReference(identifierProcessing));
|
||||
namesToValues.put(name, value);
|
||||
registerSqlType(name, sqlType);
|
||||
}
|
||||
|
||||
@@ -95,8 +95,8 @@ public class SqlParametersFactory {
|
||||
*/
|
||||
<T> SqlIdentifierParameterSource forUpdate(T instance, Class<T> domainType) {
|
||||
|
||||
return getParameterSource(instance, getRequiredPersistentEntity(domainType), "", RelationalPersistentProperty::isInsertOnly,
|
||||
dialect.getIdentifierProcessing());
|
||||
return getParameterSource(instance, getRequiredPersistentEntity(domainType), "",
|
||||
RelationalPersistentProperty::isInsertOnly, dialect.getIdentifierProcessing());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||
import org.springframework.data.relational.core.conversion.IdValueSource;
|
||||
import org.springframework.data.relational.core.dialect.AnsiDialect;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
@@ -147,6 +148,21 @@ class SqlParametersFactoryTest {
|
||||
assertThat(sqlParameterSource.getValue("value")).isEqualTo(value);
|
||||
}
|
||||
|
||||
@Test // GH-1405
|
||||
void parameterNamesGetSanitized() {
|
||||
|
||||
WithIllegalCharacters entity = new WithIllegalCharacters(23L,"aValue");
|
||||
|
||||
SqlIdentifierParameterSource sqlParameterSource = sqlParametersFactory.forInsert(entity, WithIllegalCharacters.class,
|
||||
Identifier.empty(), IdValueSource.PROVIDED);
|
||||
|
||||
assertThat(sqlParameterSource.getValue("id")).isEqualTo(23L);
|
||||
assertThat(sqlParameterSource.getValue("value")).isEqualTo("aValue");
|
||||
|
||||
assertThat(sqlParameterSource.getValue("i.d")).isNull();
|
||||
assertThat(sqlParameterSource.getValue("val&ue")).isNull();
|
||||
}
|
||||
|
||||
@WritingConverter
|
||||
enum IdValueToStringConverter implements Converter<IdValue, String> {
|
||||
|
||||
@@ -212,6 +228,16 @@ class SqlParametersFactoryTest {
|
||||
@Id private final Long id;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class WithIllegalCharacters {
|
||||
|
||||
@Column("i.d")
|
||||
@Id Long id;
|
||||
|
||||
@Column("val&ue")
|
||||
String value;
|
||||
}
|
||||
|
||||
private SqlParametersFactory createSqlParametersFactoryWithConverters(List<?> converters) {
|
||||
|
||||
BasicJdbcConverter converter = new BasicJdbcConverter(context, relationResolver,
|
||||
|
||||
@@ -104,6 +104,7 @@ import lombok.Data;
|
||||
* @author Chirag Tailor
|
||||
* @author Diego Krupitza
|
||||
* @author Christopher Klein
|
||||
* @author Mikhail Polivakha
|
||||
*/
|
||||
@Transactional
|
||||
@TestExecutionListeners(value = AssumeFeatureTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS)
|
||||
@@ -1242,8 +1243,9 @@ public class JdbcRepositoryIntegrationTests {
|
||||
assertThat(match.get().getName()).contains(two.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-1405
|
||||
void withDelimitedColumnTest() {
|
||||
|
||||
WithDelimitedColumn withDelimitedColumn = new WithDelimitedColumn();
|
||||
withDelimitedColumn.setType("TYPICAL");
|
||||
withDelimitedColumn.setIdentifier("UR-123");
|
||||
|
||||
Reference in New Issue
Block a user