diff --git a/go.mod b/go.mod index b05de1678..5dca87def 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/superseriousbusiness/activity v1.6.0-gts.0.20240408131430-247f7f7110f0 github.com/superseriousbusiness/httpsig v1.2.0-SSB github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8 - github.com/tdewolff/minify/v2 v2.20.19 + github.com/tdewolff/minify/v2 v2.20.20 github.com/technologize/otel-go-contrib v1.1.1 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/ulule/limiter/v3 v3.11.2 @@ -196,7 +196,7 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB // indirect - github.com/tdewolff/parse/v2 v2.7.12 // indirect + github.com/tdewolff/parse/v2 v2.7.13 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/toqueteos/webbrowser v1.2.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect diff --git a/go.sum b/go.sum index f09350044..562b1d1d2 100644 --- a/go.sum +++ b/go.sum @@ -552,10 +552,10 @@ github.com/superseriousbusiness/httpsig v1.2.0-SSB h1:BinBGKbf2LSuVT5+MuH0XynHN9 github.com/superseriousbusiness/httpsig v1.2.0-SSB/go.mod h1:+rxfATjFaDoDIVaJOTSP0gj6UrbicaYPEptvCLC9F28= github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8 h1:nTIhuP157oOFcscuoK1kCme1xTeGIzztSw70lX9NrDQ= github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8/go.mod h1:uYC/W92oVRJ49Vh1GcvTqpeFqHi+Ovrl2sMllQWRAEo= -github.com/tdewolff/minify/v2 v2.20.19 h1:tX0SR0LUrIqGoLjXnkIzRSIbKJ7PaNnSENLD4CyH6Xo= -github.com/tdewolff/minify/v2 v2.20.19/go.mod h1:ulkFoeAVWMLEyjuDz1ZIWOA31g5aWOawCFRp9R/MudM= -github.com/tdewolff/parse/v2 v2.7.12 h1:tgavkHc2ZDEQVKy1oWxwIyh5bP4F5fEh/JmBwPP/3LQ= -github.com/tdewolff/parse/v2 v2.7.12/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= +github.com/tdewolff/minify/v2 v2.20.20 h1:vhULb+VsW2twkplgsawAoUY957efb+EdiZ7zu5fUhhk= +github.com/tdewolff/minify/v2 v2.20.20/go.mod h1:GYaLXFpIIwsX99apQHXfGdISUdlA98wmaoWxjT9C37k= +github.com/tdewolff/parse/v2 v2.7.13 h1:iSiwOUkCYLNfapHoqdLcqZVgvQ0jrsao8YYKP/UJYTI= +github.com/tdewolff/parse/v2 v2.7.13/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= diff --git a/vendor/github.com/tdewolff/minify/v2/README.md b/vendor/github.com/tdewolff/minify/v2/README.md index 570a76816..a3c9f48f6 100644 --- a/vendor/github.com/tdewolff/minify/v2/README.md +++ b/vendor/github.com/tdewolff/minify/v2/README.md @@ -1,4 +1,4 @@ -# Minify [![API reference](https://img.shields.io/badge/godoc-reference-5272B4)](https://pkg.go.dev/github.com/tdewolff/minify/v2?tab=doc) [![Go Report Card](https://goreportcard.com/badge/github.com/tdewolff/minify)](https://goreportcard.com/report/github.com/tdewolff/minify) [![codecov](https://codecov.io/gh/tdewolff/minify/branch/master/graph/badge.svg?token=Cr7r2EKPj2)](https://codecov.io/gh/tdewolff/minify) [![Donate](https://img.shields.io/badge/patreon-donate-DFB317)](https://www.patreon.com/tdewolff) +# Minify [![API reference](https://img.shields.io/badge/godoc-reference-5272B4)](https://pkg.go.dev/github.com/tdewolff/minify/v2?tab=doc) [![Go Report Card](https://goreportcard.com/badge/github.com/tdewolff/minify)](https://goreportcard.com/report/github.com/tdewolff/minify) [![codecov](https://codecov.io/gh/tdewolff/minify/branch/master/graph/badge.svg?token=Cr7r2EKPj2)](https://codecov.io/gh/tdewolff/minify) **[Online demo](https://go.tacodewolff.nl/minify)** if you need to minify files *now*. @@ -19,11 +19,10 @@ Minify is a minifier package written in [Go][1]. It provides HTML5, CSS3, JS, JS The core functionality associates mimetypes with minification functions, allowing embedded resources (like CSS or JS within HTML files) to be minified as well. Users can add new implementations that are triggered based on a mimetype (or pattern), or redirect to an external command (like ClosureCompiler, UglifyCSS, ...). ### Sponsors +I'm actively looking for support in the form of donations or sponsorships to keep developing this library and highly appreciate any gesture. Please see the Sponsors button in GitHub for ways to contribute, or contact me directly. [![SiteGround](https://www.siteground.com/img/downloads/siteground-logo-black-transparent-vector.svg)](https://www.siteground.com/) -Please see https://www.patreon.com/tdewolff for ways to contribute, otherwise please contact me directly! - #### Table of Contents - [Minify](#minify) diff --git a/vendor/github.com/tdewolff/parse/v2/common.go b/vendor/github.com/tdewolff/parse/v2/common.go index da46cc3df..e0795304c 100644 --- a/vendor/github.com/tdewolff/parse/v2/common.go +++ b/vendor/github.com/tdewolff/parse/v2/common.go @@ -5,6 +5,7 @@ "bytes" "encoding/base64" "errors" + "strconv" ) var ( @@ -235,3 +236,307 @@ func QuoteEntity(b []byte) (quote byte, n int) { } return 0, 0 } + +// ReplaceMultipleWhitespace replaces character series of space, \n, \t, \f, \r into a single space or newline (when the serie contained a \n or \r). +func ReplaceMultipleWhitespace(b []byte) []byte { + j, k := 0, 0 // j is write position, k is start of next text section + for i := 0; i < len(b); i++ { + if IsWhitespace(b[i]) { + start := i + newline := IsNewline(b[i]) + i++ + for ; i < len(b) && IsWhitespace(b[i]); i++ { + if IsNewline(b[i]) { + newline = true + } + } + if newline { + b[start] = '\n' + } else { + b[start] = ' ' + } + if 1 < i-start { // more than one whitespace + if j == 0 { + j = start + 1 + } else { + j += copy(b[j:], b[k:start+1]) + } + k = i + } + } + } + if j == 0 { + return b + } else if j == 1 { // only if starts with whitespace + b[k-1] = b[0] + return b[k-1:] + } else if k < len(b) { + j += copy(b[j:], b[k:]) + } + return b[:j] +} + +// replaceEntities will replace in b at index i, assuming that b[i] == '&' and that i+3= '0' && b[j] <= '9' || b[j] >= 'a' && b[j] <= 'f' || b[j] >= 'A' && b[j] <= 'F'); j++ { + if b[j] <= '9' { + c = c<<4 + int(b[j]-'0') + } else if b[j] <= 'F' { + c = c<<4 + int(b[j]-'A') + 10 + } else if b[j] <= 'f' { + c = c<<4 + int(b[j]-'a') + 10 + } + } + if j <= i+3 || 10000 <= c { + return b, j - 1 + } + if c < 128 { + r = []byte{byte(c)} + } else { + r = append(r, '&', '#') + r = strconv.AppendInt(r, int64(c), 10) + r = append(r, ';') + } + } else { + c := 0 + for ; j < len(b) && c < 128 && b[j] >= '0' && b[j] <= '9'; j++ { + c = c*10 + int(b[j]-'0') + } + if j <= i+2 || 128 <= c { + return b, j - 1 + } + r = []byte{byte(c)} + } + } else { + for ; j < len(b) && j-i-1 <= MaxEntityLength && b[j] != ';'; j++ { + } + if j <= i+1 || len(b) <= j { + return b, j - 1 + } + + var ok bool + r, ok = entitiesMap[string(b[i+1:j])] + if !ok { + return b, j + } + } + + // j is at semicolon + n := j + 1 - i + if j < len(b) && b[j] == ';' && 2 < n { + if len(r) == 1 { + if q, ok := revEntitiesMap[r[0]]; ok { + if len(q) == len(b[i:j+1]) && bytes.Equal(q, b[i:j+1]) { + return b, j + } + r = q + } else if r[0] == '&' { + // check if for example & is followed by something that could potentially be an entity + k := j + 1 + if k < len(b) && (b[k] >= '0' && b[k] <= '9' || b[k] >= 'a' && b[k] <= 'z' || b[k] >= 'A' && b[k] <= 'Z' || b[k] == '#') { + return b, k + } + } + } + + copy(b[i:], r) + copy(b[i+len(r):], b[j+1:]) + b = b[:len(b)-n+len(r)] + return b, i + len(r) - 1 + } + return b, i +} + +// ReplaceEntities replaces all occurrences of entites (such as ") to their respective unencoded bytes. +func ReplaceEntities(b []byte, entitiesMap map[string][]byte, revEntitiesMap map[byte][]byte) []byte { + for i := 0; i < len(b); i++ { + if b[i] == '&' && i+3 < len(b) { + b, i = replaceEntities(b, i, entitiesMap, revEntitiesMap) + } + } + return b +} + +// ReplaceMultipleWhitespaceAndEntities is a combination of ReplaceMultipleWhitespace and ReplaceEntities. It is faster than executing both sequentially. +func ReplaceMultipleWhitespaceAndEntities(b []byte, entitiesMap map[string][]byte, revEntitiesMap map[byte][]byte) []byte { + j, k := 0, 0 // j is write position, k is start of next text section + for i := 0; i < len(b); i++ { + if IsWhitespace(b[i]) { + start := i + newline := IsNewline(b[i]) + i++ + for ; i < len(b) && IsWhitespace(b[i]); i++ { + if IsNewline(b[i]) { + newline = true + } + } + if newline { + b[start] = '\n' + } else { + b[start] = ' ' + } + if 1 < i-start { // more than one whitespace + if j == 0 { + j = start + 1 + } else { + j += copy(b[j:], b[k:start+1]) + } + k = i + } + } + if i+3 < len(b) && b[i] == '&' { + b, i = replaceEntities(b, i, entitiesMap, revEntitiesMap) + } + } + if j == 0 { + return b + } else if j == 1 { // only if starts with whitespace + b[k-1] = b[0] + return b[k-1:] + } else if k < len(b) { + j += copy(b[j:], b[k:]) + } + return b[:j] +} + +// URLEncodingTable is a charmap for which characters need escaping in the URL encoding scheme +var URLEncodingTable = [256]bool{ + // ASCII + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, false, true, true, true, true, true, false, // space, ", #, $, %, & + false, false, false, true, true, false, false, true, // +, comma, / + false, false, false, false, false, false, false, false, + false, false, true, true, true, true, true, true, // :, ;, <, =, >, ? + + true, false, false, false, false, false, false, false, // @ + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, true, true, true, true, false, // [, \, ], ^ + + true, false, false, false, false, false, false, false, // ` + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, true, true, true, false, true, // {, |, }, DEL + + // non-ASCII + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, +} + +// DataURIEncodingTable is a charmap for which characters need escaping in the Data URI encoding scheme +// Escape only non-printable characters, unicode and %, #, &. +// IE11 additionally requires encoding of \, [, ], ", <, >, `, {, }, |, ^ which is not required by Chrome, Firefox, Opera, Edge, Safari, Yandex +// To pass the HTML validator, restricted URL characters must be escaped: non-printable characters, space, <, >, #, %, " +var DataURIEncodingTable = [256]bool{ + // ASCII + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, false, true, true, false, true, true, false, // space, ", #, %, & + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, false, true, false, true, false, // <, > + + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, true, true, true, true, false, // [, \, ], ^ + + true, false, false, false, false, false, false, false, // ` + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, true, true, true, false, true, // {, |, }, DEL + + // non-ASCII + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, +} + +// EncodeURL encodes bytes using the URL encoding scheme +func EncodeURL(b []byte, table [256]bool) []byte { + for i := 0; i < len(b); i++ { + c := b[i] + if table[c] { + b = append(b, 0, 0) + copy(b[i+3:], b[i+1:]) + b[i+0] = '%' + b[i+1] = "0123456789ABCDEF"[c>>4] + b[i+2] = "0123456789ABCDEF"[c&15] + } + } + return b +} + +// DecodeURL decodes an URL encoded using the URL encoding scheme +func DecodeURL(b []byte) []byte { + for i := 0; i < len(b); i++ { + if b[i] == '%' && i+2 < len(b) { + j := i + 1 + c := 0 + for ; j < i+3 && (b[j] >= '0' && b[j] <= '9' || b[j] >= 'a' && b[j] <= 'f' || b[j] >= 'A' && b[j] <= 'F'); j++ { + if b[j] <= '9' { + c = c<<4 + int(b[j]-'0') + } else if b[j] <= 'F' { + c = c<<4 + int(b[j]-'A') + 10 + } else if b[j] <= 'f' { + c = c<<4 + int(b[j]-'a') + 10 + } + } + if j == i+3 && c < 128 { + b[i] = byte(c) + b = append(b[:i+1], b[i+3:]...) + } + } else if b[i] == '+' { + b[i] = ' ' + } + } + return b +} diff --git a/vendor/github.com/tdewolff/parse/v2/util.go b/vendor/github.com/tdewolff/parse/v2/util.go index db706d402..de8dab3df 100644 --- a/vendor/github.com/tdewolff/parse/v2/util.go +++ b/vendor/github.com/tdewolff/parse/v2/util.go @@ -1,9 +1,8 @@ package parse import ( - "bytes" "fmt" - "strconv" + "io" "unicode" ) @@ -176,306 +175,38 @@ func TrimWhitespace(b []byte) []byte { return b[start:end] } -// ReplaceMultipleWhitespace replaces character series of space, \n, \t, \f, \r into a single space or newline (when the serie contained a \n or \r). -func ReplaceMultipleWhitespace(b []byte) []byte { - j, k := 0, 0 // j is write position, k is start of next text section - for i := 0; i < len(b); i++ { - if IsWhitespace(b[i]) { - start := i - newline := IsNewline(b[i]) - i++ - for ; i < len(b) && IsWhitespace(b[i]); i++ { - if IsNewline(b[i]) { - newline = true - } - } - if newline { - b[start] = '\n' - } else { - b[start] = ' ' - } - if 1 < i-start { // more than one whitespace - if j == 0 { - j = start + 1 - } else { - j += copy(b[j:], b[k:start+1]) - } - k = i - } - } - } - if j == 0 { - return b - } else if j == 1 { // only if starts with whitespace - b[k-1] = b[0] - return b[k-1:] - } else if k < len(b) { - j += copy(b[j:], b[k:]) - } - return b[:j] +type Indenter struct { + io.Writer + b []byte } -// replaceEntities will replace in b at index i, assuming that b[i] == '&' and that i+3= '0' && b[j] <= '9' || b[j] >= 'a' && b[j] <= 'f' || b[j] >= 'A' && b[j] <= 'F'); j++ { - if b[j] <= '9' { - c = c<<4 + int(b[j]-'0') - } else if b[j] <= 'F' { - c = c<<4 + int(b[j]-'A') + 10 - } else if b[j] <= 'f' { - c = c<<4 + int(b[j]-'a') + 10 - } - } - if j <= i+3 || 10000 <= c { - return b, j - 1 - } - if c < 128 { - r = []byte{byte(c)} - } else { - r = append(r, '&', '#') - r = strconv.AppendInt(r, int64(c), 10) - r = append(r, ';') - } - } else { - c := 0 - for ; j < len(b) && c < 128 && b[j] >= '0' && b[j] <= '9'; j++ { - c = c*10 + int(b[j]-'0') - } - if j <= i+2 || 128 <= c { - return b, j - 1 - } - r = []byte{byte(c)} - } - } else { - for ; j < len(b) && j-i-1 <= MaxEntityLength && b[j] != ';'; j++ { - } - if j <= i+1 || len(b) <= j { - return b, j - 1 - } - - var ok bool - r, ok = entitiesMap[string(b[i+1:j])] - if !ok { - return b, j - } +func NewIndenter(w io.Writer, n int) Indenter { + if wi, ok := w.(Indenter); ok { + w = wi.Writer + n += len(wi.b) } - // j is at semicolon - n := j + 1 - i - if j < len(b) && b[j] == ';' && 2 < n { - if len(r) == 1 { - if q, ok := revEntitiesMap[r[0]]; ok { - if len(q) == len(b[i:j+1]) && bytes.Equal(q, b[i:j+1]) { - return b, j - } - r = q - } else if r[0] == '&' { - // check if for example & is followed by something that could potentially be an entity - k := j + 1 - if k < len(b) && (b[k] >= '0' && b[k] <= '9' || b[k] >= 'a' && b[k] <= 'z' || b[k] >= 'A' && b[k] <= 'Z' || b[k] == '#') { - return b, k - } - } - } - - copy(b[i:], r) - copy(b[i+len(r):], b[j+1:]) - b = b[:len(b)-n+len(r)] - return b, i + len(r) - 1 + b := make([]byte, n) + for i := range b { + b[i] = ' ' + } + return Indenter{ + Writer: w, + b: b, } - return b, i } -// ReplaceEntities replaces all occurrences of entites (such as ") to their respective unencoded bytes. -func ReplaceEntities(b []byte, entitiesMap map[string][]byte, revEntitiesMap map[byte][]byte) []byte { - for i := 0; i < len(b); i++ { - if b[i] == '&' && i+3 < len(b) { - b, i = replaceEntities(b, i, entitiesMap, revEntitiesMap) +func (in Indenter) Write(b []byte) (int, error) { + n, j := 0, 0 + for i, c := range b { + if c == '\n' { + m, _ := in.Writer.Write(b[j : i+1]) + n += m + m, _ = in.Writer.Write(in.b) + n += m + j = i + 1 } } - return b -} - -// ReplaceMultipleWhitespaceAndEntities is a combination of ReplaceMultipleWhitespace and ReplaceEntities. It is faster than executing both sequentially. -func ReplaceMultipleWhitespaceAndEntities(b []byte, entitiesMap map[string][]byte, revEntitiesMap map[byte][]byte) []byte { - j, k := 0, 0 // j is write position, k is start of next text section - for i := 0; i < len(b); i++ { - if IsWhitespace(b[i]) { - start := i - newline := IsNewline(b[i]) - i++ - for ; i < len(b) && IsWhitespace(b[i]); i++ { - if IsNewline(b[i]) { - newline = true - } - } - if newline { - b[start] = '\n' - } else { - b[start] = ' ' - } - if 1 < i-start { // more than one whitespace - if j == 0 { - j = start + 1 - } else { - j += copy(b[j:], b[k:start+1]) - } - k = i - } - } - if i+3 < len(b) && b[i] == '&' { - b, i = replaceEntities(b, i, entitiesMap, revEntitiesMap) - } - } - if j == 0 { - return b - } else if j == 1 { // only if starts with whitespace - b[k-1] = b[0] - return b[k-1:] - } else if k < len(b) { - j += copy(b[j:], b[k:]) - } - return b[:j] -} - -// URLEncodingTable is a charmap for which characters need escaping in the URL encoding scheme -var URLEncodingTable = [256]bool{ - // ASCII - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, false, true, true, true, true, true, false, // space, ", #, $, %, & - false, false, false, true, true, false, false, true, // +, comma, / - false, false, false, false, false, false, false, false, - false, false, true, true, true, true, true, true, // :, ;, <, =, >, ? - - true, false, false, false, false, false, false, false, // @ - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, true, true, true, true, false, // [, \, ], ^ - - true, false, false, false, false, false, false, false, // ` - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, true, true, true, false, true, // {, |, }, DEL - - // non-ASCII - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, -} - -// DataURIEncodingTable is a charmap for which characters need escaping in the Data URI encoding scheme -// Escape only non-printable characters, unicode and %, #, &. -// IE11 additionally requires encoding of \, [, ], ", <, >, `, {, }, |, ^ which is not required by Chrome, Firefox, Opera, Edge, Safari, Yandex -// To pass the HTML validator, restricted URL characters must be escaped: non-printable characters, space, <, >, #, %, " -var DataURIEncodingTable = [256]bool{ - // ASCII - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, false, true, true, false, true, true, false, // space, ", #, %, & - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, false, true, false, true, false, // <, > - - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, true, true, true, true, false, // [, \, ], ^ - - true, false, false, false, false, false, false, false, // ` - false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, - false, false, false, true, true, true, false, true, // {, |, }, DEL - - // non-ASCII - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, -} - -// EncodeURL encodes bytes using the URL encoding scheme -func EncodeURL(b []byte, table [256]bool) []byte { - for i := 0; i < len(b); i++ { - c := b[i] - if table[c] { - b = append(b, 0, 0) - copy(b[i+3:], b[i+1:]) - b[i+0] = '%' - b[i+1] = "0123456789ABCDEF"[c>>4] - b[i+2] = "0123456789ABCDEF"[c&15] - } - } - return b -} - -// DecodeURL decodes an URL encoded using the URL encoding scheme -func DecodeURL(b []byte) []byte { - for i := 0; i < len(b); i++ { - if b[i] == '%' && i+2 < len(b) { - j := i + 1 - c := 0 - for ; j < i+3 && (b[j] >= '0' && b[j] <= '9' || b[j] >= 'a' && b[j] <= 'f' || b[j] >= 'A' && b[j] <= 'F'); j++ { - if b[j] <= '9' { - c = c<<4 + int(b[j]-'0') - } else if b[j] <= 'F' { - c = c<<4 + int(b[j]-'A') + 10 - } else if b[j] <= 'f' { - c = c<<4 + int(b[j]-'a') + 10 - } - } - if j == i+3 && c < 128 { - b[i] = byte(c) - b = append(b[:i+1], b[i+3:]...) - } - } else if b[i] == '+' { - b[i] = ' ' - } - } - return b + m, err := in.Writer.Write(b[j:]) + return n + m, err } diff --git a/vendor/modules.txt b/vendor/modules.txt index 25867d74a..c58d29fbb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -801,11 +801,11 @@ github.com/superseriousbusiness/oauth2/v4/generates github.com/superseriousbusiness/oauth2/v4/manage github.com/superseriousbusiness/oauth2/v4/models github.com/superseriousbusiness/oauth2/v4/server -# github.com/tdewolff/minify/v2 v2.20.19 +# github.com/tdewolff/minify/v2 v2.20.20 ## explicit; go 1.18 github.com/tdewolff/minify/v2 github.com/tdewolff/minify/v2/html -# github.com/tdewolff/parse/v2 v2.7.12 +# github.com/tdewolff/parse/v2 v2.7.13 ## explicit; go 1.13 github.com/tdewolff/parse/v2 github.com/tdewolff/parse/v2/buffer