Fix placeholder parameter parsing

This commit is contained in:
Ingo Oppermann 2023-03-03 17:26:59 +01:00
parent 175cfc2324
commit 81473e6adb
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
3 changed files with 71 additions and 16 deletions

View File

@ -1,7 +1,6 @@
package replace
import (
"net/url"
"regexp"
"strings"
@ -125,21 +124,14 @@ func (r *replacer) parseParametes(params string, vars map[string]string, default
// taken from net/url.ParseQuery
for params != "" {
var key string
key, params, _ = strings.Cut(params, ",")
key, params, _ = cut([]rune(params), ',')
if key == "" {
continue
}
key, value, _ := strings.Cut(key, "=")
key, err := url.QueryUnescape(key)
if err != nil {
continue
}
key, value, _ := cut([]rune(key), '=')
value, err = url.QueryUnescape(value)
if err != nil {
continue
}
value = unescape([]rune(value))
for name, v := range vars {
value = strings.ReplaceAll(value, "$"+name, v)
@ -150,3 +142,49 @@ func (r *replacer) parseParametes(params string, vars map[string]string, default
return p
}
func cut(s []rune, sep rune) (before, after string, found bool) {
if i := index(s, sep); i >= 0 {
return string(s[:i]), string(s[i+1:]), true
}
return string(s), "", false
}
func index(s []rune, sep rune) int {
ignoreSep := false
for i, c := range s {
if c == rune('\\') {
ignoreSep = true
continue
}
if c == sep && !ignoreSep {
return i
}
ignoreSep = false
}
return -1
}
func unescape(e []rune) string {
r := make([]rune, len(e))
ignore := false
i := 0
for _, c := range e {
if c == rune('\\') && !ignore {
ignore = true
continue
}
ignore = false
r[i] = c
i++
}
return string(r[:i])
}

View File

@ -138,3 +138,20 @@ func TestReplaceGlob(t *testing.T) {
replaced := r.Replace("{foo:baz}, {foo:bar}", "foo:*", "", nil, nil, "")
require.Equal(t, "Hello foobaz, Hello foobar", replaced)
}
func TestParseParams(t *testing.T) {
r := New().(*replacer)
tests := [][2]string{
{"", "def"},
{"foobar=hello", "hello"},
{"foobar=%Y%m%d_%H%M%S", "%Y%m%d_%H%M%S"},
{"foobar=foo\\,bar", "foo,bar"},
{"barfoo=xxx,foobar=something", "something"},
}
for _, test := range tests {
params := r.parseParametes(test[0], nil, map[string]string{"foobar": "def"})
require.Equal(t, test[1], params["foobar"])
}
}

View File

@ -796,7 +796,7 @@ func TestReplacer(t *testing.T) {
"reference:{reference}",
"diskfs:{diskfs}/disk.txt",
"memfs:{memfs}/mem.txt",
"fsdisk:{fs:disk}/fsdisk_{date}.txt",
"fsdisk:{fs:disk}/fsdisk_{date,format=%Y%m%d_%H%M%S}.txt",
"fsmem:{fs:mem}/$inputid.txt",
},
},
@ -861,7 +861,7 @@ func TestReplacer(t *testing.T) {
"reference:refref",
"diskfs:/mnt/diskfs/disk.txt",
"memfs:http://localhost/mnt/memfs/mem.txt",
"fsdisk:/mnt/diskfs/fsdisk_{date}.txt",
"fsdisk:/mnt/diskfs/fsdisk_{date,format=%Y%m%d_%H%M%S}.txt",
"fsmem:http://localhost/mnt/memfs/$inputid.txt",
},
},
@ -924,7 +924,7 @@ func TestReplacer(t *testing.T) {
"reference:refref",
"diskfs:/mnt/diskfs/disk.txt",
"memfs:http://localhost/mnt/memfs/mem.txt",
"fsdisk:/mnt/diskfs/fsdisk_2019-10-12_07-20-50.txt",
"fsdisk:/mnt/diskfs/fsdisk_20191012_072050.txt",
"fsmem:http://localhost/mnt/memfs/$inputid.txt",
},
},
@ -1007,7 +1007,7 @@ func TestProcessReplacer(t *testing.T) {
"reference:{reference}",
"diskfs:{diskfs}/disk.txt",
"memfs:{memfs}/mem.txt",
"fsdisk:{fs:disk}/fsdisk_{date}.txt",
"fsdisk:{fs:disk}/fsdisk_{date,format=%Y%m%d_%H%M%S}.txt",
"fsmem:{fs:mem}/$inputid.txt",
},
},
@ -1075,7 +1075,7 @@ func TestProcessReplacer(t *testing.T) {
"reference:refref",
"diskfs:/mnt/diskfs/disk.txt",
"memfs:http://localhost/mnt/memfs/mem.txt",
"fsdisk:/mnt/diskfs/fsdisk_{date}.txt",
"fsdisk:/mnt/diskfs/fsdisk_{date,format=%Y%m%d_%H%M%S}.txt",
"fsmem:http://localhost/mnt/memfs/$inputid.txt",
},
Cleanup: []app.ConfigIOCleanup{},