MCPcopy Create free account
hub / github.com/egonelbre/exp / NormalizeURL

Function NormalizeURL

htmlrender/dom/util.go:36–96  ·  view source on GitHub ↗

NormalizeURL normalizes url to be safely included as an href based on golang.org/pkg/html/template

(s string)

Source from the content-addressed store, hash-verified

34// NormalizeURL normalizes url to be safely included as an href
35// based on golang.org/pkg/html/template
36func NormalizeURL(s string) string {
37 if i := strings.IndexRune(s, ':'); i >= 0 && strings.IndexRune(s[:i], '/') < 0 {
38 protocol := strings.ToLower(s[:i])
39 if protocol != "http" && protocol != "https" && protocol != "mailto" {
40 return "#ZurlZ"
41 }
42 }
43
44 var b bytes.Buffer
45 written := 0
46 // The byte loop below assumes that all URLs use UTF-8 as the
47 // content-encoding. This is similar to the URI to IRI encoding scheme
48 // defined in section 3.1 of RFC 3987, and behaves the same as the
49 // EcmaScript builtin encodeURIComponent.
50 // It should not cause any misencoding of URLs in pages with
51 // Content-type: text/html;charset=UTF-8.
52 for i, n := 0, len(s); i < n; i++ {
53 c := s[i]
54 switch c {
55 // Single quote and parens are sub-delims in RFC 3986, but we
56 // escape them so the output can be embedded in single
57 // quoted attributes and unquoted CSS url(...) constructs.
58 // Single quotes are reserved in URLs, but are only used in
59 // the obsolete "mark" rule in an appendix in RFC 3986
60 // so can be safely encoded.
61 case '!', '#', '$', '&', '*', '+', ',', '/', ':', ';', '=', '?', '@', '[', ']':
62 continue
63 // Unreserved according to RFC 3986 sec 2.3
64 // "For consistency, percent-encoded octets in the ranges of
65 // ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D),
66 // period (%2E), underscore (%5F), or tilde (%7E) should not be
67 // created by URI producers
68 case '-', '.', '_', '~':
69 continue
70 case '%':
71 // When normalizing do not re-encode valid escapes.
72 if i+2 < len(s) && isHex(s[i+1]) && isHex(s[i+2]) {
73 continue
74 }
75 default:
76 // Unreserved according to RFC 3986 sec 2.3
77 if 'a' <= c && c <= 'z' {
78 continue
79 }
80 if 'A' <= c && c <= 'Z' {
81 continue
82 }
83 if '0' <= c && c <= '9' {
84 continue
85 }
86 }
87 b.WriteString(s[written:i])
88 fmt.Fprintf(&b, "%%%02x", c)
89 written = i + 1
90 }
91 if written == 0 {
92 return s
93 }

Callers

nothing calls this directly

Calls 2

isHexFunction · 0.85
StringMethod · 0.65

Tested by

no test coverage detected