diff --git a/contrib/net/http/pattern.go b/contrib/net/http/pattern.go index 508d0503d5..98f8215d7e 100644 --- a/contrib/net/http/pattern.go +++ b/contrib/net/http/pattern.go @@ -7,9 +7,11 @@ package http import ( "errors" + "fmt" "net/http" "strings" "sync" + "unicode" "gopkg.in/DataDog/dd-trace-go.v1/internal/log" ) @@ -111,6 +113,7 @@ func parsePatternNames(pattern string) ([]string, error) { // At this point, rest is the path. var names []string + seenNames := make(map[string]bool) for len(rest) > 0 { // Invariant: rest[0] == '/'. rest = rest[1:] @@ -143,9 +146,32 @@ func parsePatternNames(pattern string) ([]string, error) { if multi && len(rest) != 0 { return nil, errors.New("{...} wildcard not at end") } + if name == "" { + return nil, errors.New("empty wildcard name") + } + if !isValidWildcardName(name) { + return nil, fmt.Errorf("bad wildcard name %q", name) + } + if seenNames[name] { + return nil, fmt.Errorf("duplicate wildcard name %q", name) + } + seenNames[name] = true names = append(names, name) } } return names, nil } + +func isValidWildcardName(s string) bool { + if s == "" { + return false + } + // Valid Go identifier. + for i, c := range s { + if !unicode.IsLetter(c) && c != '_' && (i == 0 || !unicode.IsDigit(c)) { + return false + } + } + return true +} diff --git a/contrib/net/http/pattern_test.go b/contrib/net/http/pattern_test.go index 4d124fd385..4c8fa27407 100644 --- a/contrib/net/http/pattern_test.go +++ b/contrib/net/http/pattern_test.go @@ -94,7 +94,6 @@ func TestPatternNames(t *testing.T) { {"/foo/{bar}/{baz}...", nil, true}, {"/foo/{bar", nil, true}, {"/foo/{bar{baz}}", nil, true}, - {"/foo/{bar!}", nil, true}, {"/foo/{}", nil, true}, {"{}", nil, true}, {"GET /foo/{bar}", []string{"bar"}, false}, @@ -105,7 +104,6 @@ func TestPatternNames(t *testing.T) { {"OPTIONS /foo/{bar}/{baz}...", nil, true}, {"GET /foo/{bar", nil, true}, {"POST /foo/{bar{baz}}", nil, true}, - {"PUT /foo/{bar!}", nil, true}, {"DELETE /foo/{}", nil, true}, {"OPTIONS {}", nil, true}, {"GET example.com/foo/{bar}", []string{"bar"}, false}, @@ -116,7 +114,6 @@ func TestPatternNames(t *testing.T) { {"OPTIONS example.com/foo/{bar}/{baz}...", nil, true}, {"GET example.com/foo/{bar", nil, true}, {"POST example.com/foo/{bar{baz}}", nil, true}, - {"PUT example.com/foo/{bar!}", nil, true}, {"DELETE example.com/foo/{}", nil, true}, {"OPTIONS example.com/{}", nil, true}, }