Preserve user-supplied bracket map keys when flattening YAML#36724
Open
daguimu wants to merge 1 commit intospring-projects:mainfrom
Open
Preserve user-supplied bracket map keys when flattening YAML#36724daguimu wants to merge 1 commit intospring-projects:mainfrom
daguimu wants to merge 1 commit intospring-projects:mainfrom
Conversation
YamlProcessor#buildFlattenedMap treated every key starting with '[' as an internal bracket-wrapped key (collection indices and toString() of non-CharSequence map keys) and concatenated it to the parent path without a dot. This silently dropped the literal brackets on user-supplied keys like the YAML literal '[domain.test:8080]'. Distinguish the two by checking whether the bracket-prefixed key contains characters never produced for internal keys (currently '.' and ':'). When such a separator is present the key is treated as a user-supplied map key whose original brackets are wrapped again so that downstream consumers (e.g. the Spring Boot binder) see the brackets as part of the key. Closes spring-projectsgh-27020 Signed-off-by: daguimu <daguimu.geek@gmail.com>
95ab4dd to
ece2940
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
YamlPropertiesFactoryBean(and any otherYamlProcessorconsumer) drops the literal brackets on user-supplied YAML map keys whose textual form starts with[. For example:today flattens to:
root.webservices[domain.test:8080][0].username=meso a downstream consumer such as Spring Boot's relaxed binder sees the map key as
domain.test:8080, losing the user-typed brackets entirely.Root Cause
YamlProcessor#buildFlattenedMap(spring-beans/.../YamlProcessor.java) treats every key starting with[the same way:That branch is intended for internally-generated bracket keys – collection indices (
[0],[1], …) and thetoString()of non-CharSequencemap keys (asMapline 254 wraps them as[<toString>]). When a user-supplied YAML key happens to start with[it is silently misclassified as an internal index marker and the brackets are stripped from the resulting property path.Fix
Distinguish the two cases by inspecting characters that never appear in internally-generated bracket keys:
[<digits>]toString()of common non-CharSequencekeys (Integer, Long, Boolean, …) contains no.or:So, inside the
key.startsWith("[")branch, when the key contains.or:it must have been written by the user. In that case the key is wrapped in an extra pair of brackets so the original brackets become part of the property path:asMapand the value-tree returned toYamlMapFactoryBeanusers are unchanged – the additional wrapping happens only insidebuildFlattenedMap, on the flatten path.Tests Added
.and:(the exact reproduction from the issue) is wrappedloadNestedMapWithBracketedKeyContainingDotAndColon().only is wrappedloadNestedMapWithBracketedKeyContainingDot():only is wrappedloadNestedMapWithBracketedKeyContainingColon()[0],[1], …) and Integer map keys ([1]) are unchangedloadArrayOf*andintegerKeyBehaves/integerDeepKeyBehavestests still passAll
spring-beansYAML tests (YamlPropertiesFactoryBeanTests,YamlMapFactoryBeanTests,YamlProcessorTests– 43 tests) pass locally.Impact
YamlPropertiesFactoryBean/ anyYamlProcessorconsumer that callsgetFlattenedMap: bracket-prefixed YAML keys with.or:are now preserved with an additional bracket pair, matching what the Spring Boot binder expects for map keys with special characters.YamlMapFactoryBean(tree path) and existing internal bracket keys: unchanged.Closes gh-27020