diff options
Diffstat (limited to 'modules/caddyhttp/map')
| -rw-r--r-- | modules/caddyhttp/map/caddyfile.go | 10 | ||||
| -rw-r--r-- | modules/caddyhttp/map/map.go | 26 | 
2 files changed, 25 insertions, 11 deletions
diff --git a/modules/caddyhttp/map/caddyfile.go b/modules/caddyhttp/map/caddyfile.go index f38aff7..9cc7d8c 100644 --- a/modules/caddyhttp/map/caddyfile.go +++ b/modules/caddyhttp/map/caddyfile.go @@ -27,10 +27,10 @@ func init() {  // parseCaddyfile sets up the map handler from Caddyfile tokens. Syntax:  // -//     map [<matcher>] <source> <destinations...> { -//         [~]<input> <outputs...> -//         default    <defaults...> -//     } +//	map [<matcher>] <source> <destinations...> { +//	    [~]<input> <outputs...> +//	    default    <defaults...> +//	}  //  // If the input value is prefixed with a tilde (~), then the input will be parsed as a  // regular expression. @@ -76,7 +76,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)  				continue  			} -			// every other line maps one input to one or more outputs +			// every line maps an input value to one or more outputs  			in := h.Val()  			var outs []any  			for h.NextArg() { diff --git a/modules/caddyhttp/map/map.go b/modules/caddyhttp/map/map.go index bbc1249..d41806d 100644 --- a/modules/caddyhttp/map/map.go +++ b/modules/caddyhttp/map/map.go @@ -62,6 +62,9 @@ func (Handler) CaddyModule() caddy.ModuleInfo {  // Provision sets up h.  func (h *Handler) Provision(_ caddy.Context) error {  	for j, dest := range h.Destinations { +		if strings.Count(dest, "{") != 1 || !strings.HasPrefix(dest, "{") { +			return fmt.Errorf("destination must be a placeholder and only a placeholder") +		}  		h.Destinations[j] = strings.Trim(dest, "{}")  	} @@ -106,6 +109,16 @@ func (h *Handler) Validate() error {  		}  		seen[input] = i +		// prevent infinite recursion +		for _, out := range m.Outputs { +			for _, dest := range h.Destinations { +				if strings.Contains(caddy.ToString(out), dest) || +					strings.Contains(m.Input, dest) { +					return fmt.Errorf("mapping %d requires value of {%s} to define value of {%s}: infinite recursion", i, dest, dest) +				} +			} +		} +  		// ensure mappings have 1:1 output-to-destination correspondence  		nOut := len(m.Outputs)  		if nOut != nDest { @@ -135,21 +148,22 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt  			if output == nil {  				continue  			} +			outputStr := caddy.ToString(output) + +			// evaluate regular expression if configured  			if m.re != nil {  				var result []byte  				matches := m.re.FindStringSubmatchIndex(input)  				if matches == nil {  					continue  				} -				result = m.re.ExpandString(result, output.(string), input, matches) +				result = m.re.ExpandString(result, outputStr, input, matches)  				return string(result), true  			} + +			// otherwise simple string comparison  			if input == m.Input { -				if outputStr, ok := output.(string); ok { -					// NOTE: if the output has a placeholder that has the same key as the input, this is infinite recursion -					return repl.ReplaceAll(outputStr, ""), true -				} -				return output, true +				return repl.ReplaceAll(outputStr, ""), true  			}  		}  | 
