Copyright (c) 2017 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 or at https://developers.google.com/open-source/licenses/bsd
Package safehtmlutil contains functions shared by package safehtml and safehtml/template.
package safehtmlutil

import (
	
	
	
	
)
IsSafeTrustedResourceURLPrefix returns whether the given prefix is safe to use as a TrustedResourceURL prefix. TrustedResourceURL prefixes must start with one of the following: * `https://<origin>/` * `//<origin>/` * `/<pathStart>` * `about:blank#` `<origin>` must contain only alphanumerics, '.', ':', '[', ']', or '-'. These restrictions do not enforce a well-formed domain name, so '.' and '1.2' are valid. `<pathStart>` is any character except `/` and `\`. Based on https://url.spec.whatwg.org/commit-snapshots/56b74ce7cca8883eab62e9a12666e2fac665d03d/#url-parsing, an initial / which is not followed by another / or \ will end up in the "path state" and from there it can only go to the "fragment state" and "query state".
func ( string) bool {
	return safeTrustedResourceURLPrefixPattern.MatchString()
}

var safeTrustedResourceURLPrefixPattern = regexp.MustCompile(`(?i)^(?:` +
	`(?:https:)?//[0-9a-z.:\[\]-]+/|` +
	`/[^/\\]|` +
	`about:blank#)`)
URLContainsDoubleDotSegment returns whether the given URL or URL substring contains the double dot-segment ".." (RFC3986 3.3) in its percent-encoded or unencoded form.
QueryEscapeURL produces an output that can be embedded in a URL query. The output can be embedded in an HTML attribute without further escaping.
func ( ...interface{}) string {
	return urlProcessor(false, Stringify(...))
}
NormalizeURL normalizes URL content so it can be embedded in a quote-delimited string or parenthesis delimited url(...). The normalizer does not encode all HTML specials. Specifically, it does not encode '&' so correct embedding in an HTML attribute requires escaping of '&' to '&amp;'.
func ( ...interface{}) string {
	return urlProcessor(true, Stringify(...))
}
urlProcessor normalizes (when norm is true) or escapes its input to produce a valid hierarchical or opaque URL part.
func ( bool,  string) string {
	var  bytes.Buffer
The byte loop below assumes that all URLs use UTF-8 as the content-encoding. This is similar to the URI to IRI encoding scheme defined in section 3.1 of RFC 3987, and behaves the same as the EcmaScript builtin encodeURIComponent. It should not cause any misencoding of URLs in pages with Content-type: text/html;charset=UTF-8.
	for ,  := 0, len();  < ; ++ {
		 := []
Single quote and parens are sub-delims in RFC 3986, but we escape them so the output can be embedded in single quoted attributes and unquoted CSS url(...) constructs. Single quotes are reserved in URLs, but are only used in the obsolete "mark" rule in an appendix in RFC 3986 so can be safely encoded.
		case '!', '#', '$', '&', '*', '+', ',', '/', ':', ';', '=', '?', '@', '[', ']':
			if  {
				continue
Unreserved according to RFC 3986 sec 2.3 "For consistency, percent-encoded octets in the ranges of ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should not be created by URI producers
		case '-', '.', '_', '~':
			continue
When normalizing do not re-encode valid escapes.
			if  && +2 < len() && isHex([+1]) && isHex([+2]) {
				continue
			}
Unreserved according to RFC 3986 sec 2.3
			if 'a' <=  &&  <= 'z' {
				continue
			}
			if 'A' <=  &&  <= 'Z' {
				continue
			}
			if '0' <=  &&  <= '9' {
				continue
			}
		}
		.WriteString([:])
		fmt.Fprintf(&, "%%%02x", )
		 =  + 1
	}
	if  == 0 {
		return 
	}
	.WriteString([:])
	return .String()
}
isHex reports whether the given character is a hex digit.
func ( byte) bool {
	return '0' <=  &&  <= '9' || 'a' <=  &&  <= 'f' || 'A' <=  &&  <= 'F'
}
Stringify converts its arguments to a string. It is equivalent to fmt.Sprint(args...), except that it deferences all pointers.
Optimization for simple common case of a single string argument.
	if len() == 1 {
		if ,  := [0].(string);  {
			return 
		}
	}
	for ,  := range  {
		[] = indirectToStringerOrError()
	}
	return fmt.Sprint(...)
}

var (
	errorType       = reflect.TypeOf((*error)(nil)).Elem()
	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
)
indirectToStringerOrError dereferences a as many times as necessary to reach the base type, an implementation of fmt.Stringer, or an implementation of error, and returns a value of that type. It returns nil if a is nil.
func ( interface{}) interface{} {
	if  == nil {
		return nil
	}
	 := reflect.ValueOf()
	for !.Type().Implements(fmtStringerType) && !.Type().Implements(errorType) && .Kind() == reflect.Ptr && !.IsNil() {
		 = .Elem()
	}
	return .Interface()
}
Indirect returns the value, after dereferencing as many times as necessary to reach the base type (or nil).
func ( interface{}) interface{} {
	if  == nil {
		return nil
	}
Avoid creating a reflect.Value if it's not a pointer.
		return 
	}
	 := reflect.ValueOf()
	for .Kind() == reflect.Ptr && !.IsNil() {
		 = .Elem()
	}
	return .Interface()