From a08ab0c00743c2d00e210e4ac3f9f38e2bbee951 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Wed, 14 Aug 2019 10:41:25 -0600 Subject: [PATCH] Fix slice bounds when getting key of address (fixes #2706) --- caddyhttp/httpserver/plugin.go | 19 ++++++++++--------- caddyhttp/httpserver/plugin_test.go | 24 ++++++++++++++++++++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/caddyhttp/httpserver/plugin.go b/caddyhttp/httpserver/plugin.go index 19e814d70..378e9cb8f 100644 --- a/caddyhttp/httpserver/plugin.go +++ b/caddyhttp/httpserver/plugin.go @@ -490,11 +490,10 @@ func (a Address) Key() string { if a.Host != "" { res += a.Host } - if a.Port != "" { - if strings.HasPrefix(a.Original[len(res):], ":"+a.Port) { - // insert port only if the original has its own explicit port - res += ":" + a.Port - } + // insert port only if the original has its own explicit port + if a.Port != "" && len(a.Original) >= len(res) && + strings.HasPrefix(a.Original[len(res):], ":"+a.Port) { + res += ":" + a.Port } if a.Path != "" { res += a.Path @@ -553,10 +552,12 @@ func standardizeAddress(str string) (Address, error) { // standardize http and https ports to their respective port numbers // (this behavior changed in Go 1.12.8) - if port == httpPort { - u.Scheme = "http" - } else if port == httpsPort { - u.Scheme = "https" + if u.Scheme == "" { + if port == httpPort { + u.Scheme = "http" + } else if port == httpsPort { + u.Scheme = "https" + } } return Address{Original: input, Scheme: u.Scheme, Host: host, Port: port, Path: u.Path}, nil diff --git a/caddyhttp/httpserver/plugin_test.go b/caddyhttp/httpserver/plugin_test.go index 6e20a858d..86db362a3 100644 --- a/caddyhttp/httpserver/plugin_test.go +++ b/caddyhttp/httpserver/plugin_test.go @@ -43,8 +43,8 @@ func TestStandardizeAddress(t *testing.T) { {`:`, "", "", "", "", false}, {`localhost:http`, "http", "localhost", "80", "", false}, {`localhost:https`, "https", "localhost", "443", "", false}, - {`:http`, "http", "", "80", "", false}, - {`:https`, "https", "", "443", "", false}, + {`:http`, "http", "", "80", "", false}, // as of Go 1.12.8, service name in port is no longer supported + {`:https`, "https", "", "443", "", false}, // as of Go 1.12.8, service name in port is no longer supported {`http://localhost:https`, "", "", "", "", true}, // conflict {`http://localhost:http`, "http", "localhost", "80", "", false}, // repeated scheme -- test adjusted for Go 1.12.8 (expect no error) {`http://localhost:443`, "", "", "", "", true}, // not conventional @@ -212,6 +212,10 @@ func TestKeyNormalization(t *testing.T) { orig string res string }{ + { + orig: "http://host:1234/path", + res: "http://host:1234/path", + }, { orig: "HTTP://A/ABCDEF", res: "http://a/ABCDEF", @@ -221,8 +225,20 @@ func TestKeyNormalization(t *testing.T) { res: "a/ABCDEF", }, { - orig: "A:2015/Port", - res: "a:2015/Port", + orig: "A:2015/Path", + res: "a:2015/Path", + }, + { + orig: ":80", + res: "http://", + }, + { + orig: ":443", + res: "https://", + }, + { + orig: ":1234", + res: ":1234", }, } for _, item := range caseSensitiveData {