From ad90b273dbb13bf45644f39f6c0be1248c943d9a Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Mon, 11 Nov 2019 19:29:31 -0700 Subject: [PATCH] core: Add tests to Replacer; fix panic (fixes #2852) --- replacer.go | 9 ++++--- replacer_test.go | 68 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/replacer.go b/replacer.go index c82d81dc0..a38cf5577 100644 --- a/replacer.go +++ b/replacer.go @@ -116,11 +116,14 @@ func (r *replacer) replace(input, empty string, continue } - // write the substring from the last cursor to this point - sb.WriteString(input[lastWriteCursor:i]) - // find the end of the placeholder end := strings.Index(input[i:], string(phClose)) + i + if end < i { + continue + } + + // write the substring from the last cursor to this point + sb.WriteString(input[lastWriteCursor:i]) // trim opening bracket key := input[i+1 : end] diff --git a/replacer_test.go b/replacer_test.go index 435582bb6..fa9b56930 100644 --- a/replacer_test.go +++ b/replacer_test.go @@ -22,16 +22,62 @@ import ( "testing" ) -func fakeReplacer() replacer { - return replacer{ - providers: make([]ReplacementFunc, 0), - static: make(map[string]string), +func TestReplacer(t *testing.T) { + type testCase struct { + input, expect, empty string + } + + rep := testReplacer() + + // ReplaceAll + for i, tc := range []testCase{ + { + input: "{", + expect: "{", + }, + { + input: "foo{", + expect: "foo{", + }, + { + input: "foo{bar", + expect: "foo{bar", + }, + { + input: "foo{bar}", + expect: "foo", + }, + { + input: "}", + expect: "}", + }, + { + input: "{}", + expect: "", + }, + { + input: `{"json": "object"}`, + expect: "", + }, + { + input: `{{`, + expect: "{{", + }, + { + input: `{{}`, + expect: "", + }, + } { + actual := rep.ReplaceAll(tc.input, tc.empty) + if actual != tc.expect { + t.Errorf("Test %d: '%s': expected '%s' but got '%s'", + i, tc.input, tc.expect, actual) + } } } -// Tests the Set method by setting some variables and check if they are added to static func TestReplacerSet(t *testing.T) { - rep := fakeReplacer() + rep := testReplacer() for _, tc := range []struct { variable string @@ -191,7 +237,7 @@ func TestReplacerDelete(t *testing.T) { } func TestReplacerMap(t *testing.T) { - rep := fakeReplacer() + rep := testReplacer() for i, tc := range []ReplacementFunc{ func(key string) (val string, ok bool) { @@ -228,6 +274,7 @@ func TestReplacerNew(t *testing.T) { // test if default global replacements are added as the first provider hostname, _ := os.Hostname() os.Setenv("CADDY_REPLACER_TEST", "envtest") + defer os.Setenv("CADDY_REPLACER_TEST", "") for _, tc := range []struct { variable string @@ -267,3 +314,10 @@ func TestReplacerNew(t *testing.T) { t.Errorf("Expected type of replacer %T got %T ", &replacer{}, tc) } } + +func testReplacer() replacer { + return replacer{ + providers: make([]ReplacementFunc, 0), + static: make(map[string]string), + } +}