diff options
author | Nathan Friend <hello@nathanfriend.io> | 2021-08-21 19:37:34 +0300 |
---|---|---|
committer | Jaime Martinez <jmartinez@gitlab.com> | 2021-08-25 10:29:45 +0300 |
commit | 65188a6f442d2fa5f34be815564c151f3a52e8a7 (patch) | |
tree | 9dcafe2a982470ca51fcc99ce4ba623faa49be98 | |
parent | 14c87e2392d2ac64a3b820cb60b829d45d58443f (diff) |
feat: Add _redirects max rule count validation
This commit adds a new validation that ensures a _redirects file doesn't
contain too many rules.
Changelog: changed
-rw-r--r-- | internal/redirects/matching.go | 4 | ||||
-rw-r--r-- | internal/redirects/redirects.go | 10 | ||||
-rw-r--r-- | internal/redirects/validations.go | 12 |
3 files changed, 25 insertions, 1 deletions
diff --git a/internal/redirects/matching.go b/internal/redirects/matching.go index 913cb359..fb879e4f 100644 --- a/internal/redirects/matching.go +++ b/internal/redirects/matching.go @@ -100,6 +100,10 @@ func matchesRule(rule *netlifyRedirects.Rule, path string) (bool, string) { // // If no rule matches, this function returns `nil` and an empty string func (r *Redirects) match(path string) (*netlifyRedirects.Rule, string) { + if validateRedirectsFile(r) != nil { + return nil, "" + } + for i := range r.rules { // assign rule to a new var to prevent the following gosec error // G601: Implicit memory aliasing in for loop diff --git a/internal/redirects/redirects.go b/internal/redirects/redirects.go index 79fa8dd6..fafeaf4b 100644 --- a/internal/redirects/redirects.go +++ b/internal/redirects/redirects.go @@ -30,6 +30,9 @@ const ( // maxPathSegments is used to limit the number of path segments allowed in rules URLs maxPathSegments = 25 + // maxRuleCount is used to limit the total number of rules allowed in _redirects + maxRuleCount = 1000 + // FFEnablePlaceholders used to check whether placeholder matching is enabled or not FFEnablePlaceholders = "FF_ENABLE_PLACEHOLDERS" ) @@ -51,7 +54,8 @@ var ( errNoParams = errors.New("params not supported") errUnsupportedStatus = errors.New("status not supported") errNoForce = errors.New("force! not supported") - errTooManyPathSegments = errors.New("url path cannot contain more than 25 forward slashes") + errTooManyPathSegments = fmt.Errorf("url path cannot contain more than %d forward slashes", maxPathSegments) + errTooManyRules = fmt.Errorf("_redirects file may not contain more than %d rules", maxRuleCount) regexpPlaceholder = regexp.MustCompile(`(?i)/:[a-z]+`) ) @@ -69,6 +73,10 @@ func (r *Redirects) Status() string { messages := make([]string, 0, len(r.rules)+1) messages = append(messages, fmt.Sprintf("%d rules", len(r.rules))) + if err := validateRedirectsFile(r); err != nil { + messages = append(messages, fmt.Sprintf("error: %s", err.Error())) + } + for i, rule := range r.rules { if err := validateRule(rule); err != nil { messages = append(messages, fmt.Sprintf("rule %d: error: %s", i+1, err.Error())) diff --git a/internal/redirects/validations.go b/internal/redirects/validations.go index 1af5c5c5..7c6d8089 100644 --- a/internal/redirects/validations.go +++ b/internal/redirects/validations.go @@ -89,3 +89,15 @@ func validateRule(r netlifyRedirects.Rule) error { return nil } + +// validateRedirectsFile runs rules on the _redirects file as a whole. +// Returns `nil` if no errors are found. +// Does not run rule-specific validations - this is +// handled by `validateRule` instead. +func validateRedirectsFile(r *Redirects) error { + if len(r.rules) > maxRuleCount { + return errTooManyRules + } + + return nil +} |