Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package template

import (
	
	
	
)
sanitizerForContext returns an ordered list of function names that will be called to sanitize data values found in the HTML context defined by c.
func ( context) ([]string, error) {
	switch .state {
	case stateTag, stateAttrName, stateAfterName:
		return nil, fmt.Errorf("actions must not affect element or attribute names")
	case stateHTMLCmt:
		return []string{sanitizeHTMLCommentFuncName}, nil
	}
Not in an HTML element.
We are in an attribute value context.
TODO: consider disallowing single-quoted or unquoted attribute values completely, even in hardcoded template text.
			return nil, fmt.Errorf("unquoted attribute values disallowed")
		}
		return sanitizersForAttributeValue()
Otherwise, we are in an element content context.
	,  := sanitizerForElementContent()
	return appendIfNotEmpty([]string{}, ), 
}
appendIfNotEmpty appends the given strings that are non-empty to the given slice.
func ( []string,  ...string) []string {
	for ,  := range  {
		if  != "" {
			 = append(, )
		}
	}
	return 
}
sanitizersForAttributeValue returns a list of names of functions that will be called in order to sanitize data values found the HTML attribtue value context c.
Ensure that all combinations of element and attribute names for this context results in the same attribute value sanitization context.
	var ,  []string
	if len(.element.names) == 0 {
		 = []string{.element.name}
	} else {
		 = .element.names
	}
	if len(.attr.names) == 0 {
		 = []string{.attr.name}
	} else {
		 = .attr.names
	}
	var  sanitizationContext
	var ,  string
	for ,  := range  {
		for ,  := range  {
			,  := sanitizationContextForAttrVal(, , .linkRel)
			if  != nil {
				if len() == 1 && len() == 1 {
					return nil, 
				}
				return nil, fmt.Errorf(`conditional branch with {element=%q, attribute=%q} results in sanitization error: %s`, , , )
			}
			if  == 0 &&  == 0 {
				, ,  = , , 
				continue
			}
			if  !=  {
				return nil, fmt.Errorf(
					`conditional branches end in different attribute value sanitization contexts: {element=%q, attribute=%q} has sanitization context %q, {element=%q, attribute=%q} has sanitization context %q`,
					, , , , , )
			}
		}
	}
	if .isEnum() && .attr.value != "" {
		return nil, fmt.Errorf("partial substitutions are disallowed in the %q attribute value context of a %q element", .attr.name, .element.name)
	}
	if  == sanitizationContextStyle && .attr.value != "" {
		if  := validateDoesNotEndsWithCharRefPrefix(.attr.value);  != nil {
			return nil, fmt.Errorf("action cannot be interpolated into the %q attribute value of this %q element: %s", .attr.name, .element.name, )
		}
ret is a stack of sanitizer names that will be built in reverse.
All attribute values must be HTML-escaped at run time by sanitizeHTML to eliminate any HTML markup that can cause the HTML parser to transition out of the attribute value state. These attribute values will later be HTML-unescaped by the HTML parser in the browser.
	 = append(, sanitizeHTMLFuncName)
	 := .sanitizerName()
	if !.isURLorTrustedResourceURL() {
		return reverse(appendIfNotEmpty(, )), nil
	}
	 := .attr.value
Attribute value prefixes in URL or TrustedResourceURL sanitization contexts must sanitized and normalized.
		return reverse(appendIfNotEmpty(, normalizeURLFuncName, )), nil
Action occurs after a URL or TrustedResourceURL prefix.
	if .attr.ambiguousValue {
		return nil, fmt.Errorf("actions must not occur after an ambiguous URL prefix in the %q attribute value context of a %q element", .attr.name, .element.name)
	}
	,  := urlPrefixValidators[]
	if ! {
		return nil, fmt.Errorf("cannot validate attribute value prefix %q in the %q sanitization context", .attr.value, )
	}
	if  := (.attr.value);  != nil {
		return nil, fmt.Errorf("action cannot be interpolated into the %q URL attribute value of this %q element: %s", .attr.name, .element.name, )
	}
	switch {
Untrusted data that occurs anywhere after TrustedResourceURL prefix must be query-escaped to prevent the injection of any new path segments or URL components. Moreover, they must not contain any ".." dot-segments.
For URLs, we only escape in the query or fragment part to prevent the injection of new query parameters or fragments.
		 = append(, queryEscapeURLFuncName)
	default:
		 = append(, normalizeURLFuncName)
	}
	return reverse(), nil
}
reverse reverses s and returns it.
func ( []string) []string {
	for ,  := 0, len()-1;  < ; ,  = +1, -1 {
		[], [] = [], []
	}
	return 
}
sanitizationContextForAttrVal returns the sanitization context for attr when it appears within element.
Special case: safehtml.URL values are allowed in a link element's href attribute if that element's rel attribute possesses certain values.
		 := strings.Fields()
		for ,  := range  {
			if urlLinkRelVals[] {
				return sanitizationContextTrustedResourceURLOrURL, nil
			}
		}
	}
Special case: data-* attributes are specified by HTML5 to hold custom data private to the page or application; they should not be interpreted by browsers. Therefore, no sanitization is required for these attribute values.
		return sanitizationContextNone, nil
	}
	if ,  := elementSpecificAttrValSanitizationContext[][];  {
		return , nil
	}
	,  := globalAttrValSanitizationContext[]
	,  := elementContentSanitizationContext[]
Only sanitize attributes that appear in elements whose semantics are known. Thes attributes might have different semantics in other standard or custom elements that our sanitization policy does not handle correctly.
		return , nil
	}
	return 0, fmt.Errorf("actions must not occur in the %q attribute value context of a %q element", , )
}
dataAttributeNamePattern matches valid data attribute names. This pattern is conservative and matches only a subset of the valid names defined in https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes
var dataAttributeNamePattern = regexp.MustCompile(`^data-[a-z_][-a-z0-9_]*$`)
endsWithCharRefPrefixPattern matches strings that end in an incomplete HTML character reference. See https://html.spec.whatwg.org/multipage/syntax.html#character-references.
var endsWithCharRefPrefixPattern = regexp.MustCompile(
	`&(?:[[:alpha:]][[:alnum:]]*|#(?:[xX][[:xdigit:]]*|[[:digit:]]*))?$`)
validateDoesNotEndsWithCharRefPrefix returns an error only if the given prefix ends with an incomplete HTML character reference.
func ( string) error {
	if endsWithCharRefPrefixPattern.MatchString() {
		return fmt.Errorf(`prefix %q ends with an incomplete HTML character reference; did you mean "&amp;" instead of "&"?`, )
	}
	return nil
}
sanitizerForElementContent returns the name of the function that will be called to sanitize data values found in the HTML element content context c.
Ensure that all other possible element names for this context result in the same element content sanitization context.
	var  []string
	if len(.element.names) == 0 {
		 = []string{.element.name}
	} else {
		 = .element.names
	}
	var  sanitizationContext
	var  string
	for ,  := range  {
		var  sanitizationContext
		var  error
Special case: an empty element name represents a context outside of a HTML element.
			 = sanitizationContextHTML
		} else {
			,  = sanitizationContextForElementContent()
		}
		if  != nil {
			if len() == 1 {
				return "", 
			}
			return "", fmt.Errorf(`conditional branch with element %q results in sanitization error: %s`, , )
		}
		if  == 0 {
			,  = , 
			continue
		}
		if  !=  {
			return "",
				fmt.Errorf(`conditional branches end in different element content sanitization contexts: element %q has sanitization context %q, element %q has sanitization context %q`,
					, , , )
		}
	}
	return .sanitizerName(), nil
}
sanitizationContextForElementContent returns the element content sanitization context for the given element.
func ( string) (sanitizationContext, error) {
	,  := elementContentSanitizationContext[]
	if ! {
		return 0, fmt.Errorf("actions must not occur in the element content context of a %q element", )
	}
	return , nil
}
sanitizeHTMLComment returns the empty string regardless of input. Comment content does not correspond to any parsed structure or human-readable content, so the simplest and most secure policy is to drop content interpolated into comments. This approach is equally valid whether or not static comment content is removed from the template.
func ( ...interface{}) string {
	return ""