Skip to content

Commit 4d5ed2c

Browse files
Bensionliaogs
andauthored
fix(conf): support equal signs in property values (#5392)
Co-authored-by: liaogs <liaoguoshun@qq.com>
1 parent a2310bf commit 4d5ed2c

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

core/conf/properties.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func LoadProperties(filename string, opts ...Option) (Properties, error) {
4545

4646
raw := make(map[string]string)
4747
for i := range lines {
48-
pair := strings.Split(lines[i], "=")
48+
pair := strings.SplitN(lines[i], "=", 2)
4949
if len(pair) != 2 {
5050
// invalid property format
5151
return nil, &PropertyError{

core/conf/properties_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,70 @@ func TestLoadBadFile(t *testing.T) {
9292
_, err := LoadProperties("nosuchfile")
9393
assert.NotNil(t, err)
9494
}
95+
96+
func TestProperties_valueWithEqualSymbols(t *testing.T) {
97+
text := `# test with equal symbols in value
98+
db.url=postgres://localhost:5432/db?param=value
99+
math.equation=a=b=c
100+
base64.data=SGVsbG8=World=Test=
101+
url.with.params=http://example.com?foo=bar&baz=qux
102+
empty.value=
103+
key.with.space = value = with = equals`
104+
tmpfile, err := fs.TempFilenameWithText(text)
105+
assert.Nil(t, err)
106+
defer os.Remove(tmpfile)
107+
108+
props, err := LoadProperties(tmpfile)
109+
assert.Nil(t, err)
110+
assert.Equal(t, "postgres://localhost:5432/db?param=value", props.GetString("db.url"))
111+
assert.Equal(t, "a=b=c", props.GetString("math.equation"))
112+
assert.Equal(t, "SGVsbG8=World=Test=", props.GetString("base64.data"))
113+
assert.Equal(t, "http://example.com?foo=bar&baz=qux", props.GetString("url.with.params"))
114+
assert.Equal(t, "", props.GetString("empty.value"))
115+
assert.Equal(t, "value = with = equals", props.GetString("key.with.space"))
116+
}
117+
118+
func TestProperties_edgeCases(t *testing.T) {
119+
tests := []struct {
120+
name string
121+
content string
122+
wantErr bool
123+
errMsg string
124+
}{
125+
{
126+
name: "no equal sign",
127+
content: "invalid line without equal",
128+
wantErr: true,
129+
},
130+
{
131+
name: "only equal sign",
132+
content: "=",
133+
wantErr: false, // "=" 会被解析为空 key 和空 value,len(pair) == 2,是合法的
134+
},
135+
{
136+
name: "empty key",
137+
content: "=value",
138+
wantErr: false, // 空 key 也会被 trim,但 len(pair) == 2 所以不会报错
139+
},
140+
{
141+
name: "equal at end",
142+
content: "key.name=",
143+
wantErr: false, // 空 value 是合法的
144+
},
145+
}
146+
147+
for _, tt := range tests {
148+
t.Run(tt.name, func(t *testing.T) {
149+
tmpfile, err := fs.TempFilenameWithText(tt.content)
150+
assert.Nil(t, err)
151+
defer os.Remove(tmpfile)
152+
153+
_, err = LoadProperties(tmpfile)
154+
if tt.wantErr {
155+
assert.NotNil(t, err, "expected error for case: %s", tt.name)
156+
} else {
157+
assert.Nil(t, err, "unexpected error for case: %s", tt.name)
158+
}
159+
})
160+
}
161+
}

0 commit comments

Comments
 (0)