From 81473e6adb2b53ff349b93a3c2aa06ae317d75a1 Mon Sep 17 00:00:00 2001 From: Ingo Oppermann Date: Fri, 3 Mar 2023 17:26:59 +0100 Subject: [PATCH] Fix placeholder parameter parsing --- restream/replace/replace.go | 60 ++++++++++++++++++++++++++------ restream/replace/replace_test.go | 17 +++++++++ restream/restream_test.go | 10 +++--- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/restream/replace/replace.go b/restream/replace/replace.go index 9dd534d6..5babd0bc 100644 --- a/restream/replace/replace.go +++ b/restream/replace/replace.go @@ -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]) +} diff --git a/restream/replace/replace_test.go b/restream/replace/replace_test.go index dc0d6765..2e4a613a 100644 --- a/restream/replace/replace_test.go +++ b/restream/replace/replace_test.go @@ -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"]) + } +} diff --git a/restream/restream_test.go b/restream/restream_test.go index 79d96e8f..3feaddf4 100644 --- a/restream/restream_test.go +++ b/restream/restream_test.go @@ -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{},