Affects: since 4.1
I am trying to fix the #27020 , but meet one exists test case failed. But I really think the failed test case is a anti-use of numberic indexed map of Yaml.
https://github.com/spring-projects/spring-framework/blob/58e9b187fedf03da21c4e2270bb5335b941ccf61/spring-beans/src/test/java/org/springframework/beans/factory/config/YamlProcessorTests.java#L108-L115
In the test case, it wrapped the numberic index of yaml as a bracket escaped key and verify the final key.
Problems in code
https://github.com/spring-projects/spring-framework/blob/58e9b187fedf03da21c4e2270bb5335b941ccf61/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java#L230-L252
in Line 248 it wrap all non-string key with bracket. Is it wrong?
https://github.com/spring-projects/spring-framework/blob/58e9b187fedf03da21c4e2270bb5335b941ccf61/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java#L248
Comment From: ian4hu
Should Spring need reject all invalid/non-string key or only wrap key with special chars?
example yaml
root:
1: positive integer
-1: negative integer
1.1: positive decimal
-1.1: negative decimal
true: ok
equivalent json
{
"root": {
"1": "positive integer",
"-1": "negative integer",
"1.1": "positive decimal",
"-1.1": "negative decimal",
"true": "ok"
}
}
Reject all invalid/non-string key
- string accepted as it is. (may contains special chars like [
)
- positive long/integer number accepted as plain toString()
- negative long/integer number like -1 rejected with illegal argument
- decimal like 1.1 rejected with illegal argument
- char accepted as plain toString()
- others accepted as plain toString(), (but may contains special chars like [
)
root:
1: positive integer
-1: negative integer <- illegal argument
1.1: positive decimal <- illegal argument
-1.1: negative decimal <- illegal argument
true: ok
Or:
Accept all keys, but escape special key with brackets
- string if it contains special chars like
.
/
[
etc, wrap it with brackets likea.b
->[a.b]
- integer number accepted as toString(), negative number will not be wrapped like
-1
->-1
- decimal number accepted as toString() but with bracket wrapped around.
-1.0
->[-1.0]
1.0
->[1.0]
- other types accepted as plain toString(), wrap only when it contains special chars.
parse example yaml as bellow properties
root.1 = positive integer
root.-1 = negative integer
root.[1.1] = positive decimal
root.[-1.1] = negative decimal
root.true = ok
Comment From: ian4hu
related https://github.com/spring-cloud/spring-cloud-config/issues/1595
Comment From: j4zzcat
I stumbled upon this bug myself -- there's something broken also when using trailing zeros. See the following test case in Kotlin.
package bugs
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.core.env.PropertiesPropertySource
import org.springframework.core.io.InputStreamResource
import org.springframework.stereotype.Component
@SpringBootApplication
class Main
fun main(args: Array<String>) {
runApplication<Main>(*args)
}
@Component
class Testcase {
init {
val testcase =
"""
foo:
7: G
8: H
9: I
10: J
bar:
07: G
08: H
09: I
10: J
""".trimIndent()
val factory = YamlPropertiesFactoryBean()
factory.setResources(InputStreamResource(testcase.byteInputStream()))
val p = PropertiesPropertySource("testcase", factory.getObject()!!)
p.propertyNames.forEach(::println)
}
}
Which produces:
bar.08 <-- doh
bar.09 <-- doh!
bar[10] <-- ok
bar[7] <-- ok
foo[10] <-- ok
foo[7] <-- ok
foo[8] <-- ok
foo[9] <-- ok
Comment From: snicoll
in Line 248 it wrap all non-string key with bracket. Is it wrong?
No. Please note that YamlProcessor
and the companion classes are mainly intended to map a yaml configuration file to a property source. As such, it does not intend to preserve the type of intermediate elements.
Duplicates of #24608