snapshot of https://github.com/go-gitea/gitea.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped
Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped
This commit is contained in:
56
modules/svg/processor.go
Normal file
56
modules/svg/processor.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package svg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type globalVarsStruct struct {
|
||||
reXMLDoc,
|
||||
reComment,
|
||||
reAttrXMLNs,
|
||||
reAttrSize,
|
||||
reAttrClassPrefix *regexp.Regexp
|
||||
}
|
||||
|
||||
var globalVars = sync.OnceValue(func() *globalVarsStruct {
|
||||
return &globalVarsStruct{
|
||||
reXMLDoc: regexp.MustCompile(`(?s)<\?xml.*?>`),
|
||||
reComment: regexp.MustCompile(`(?s)<!--.*?-->`),
|
||||
|
||||
reAttrXMLNs: regexp.MustCompile(`(?s)\s+xmlns\s*=\s*"[^"]*"`),
|
||||
reAttrSize: regexp.MustCompile(`(?s)\s+(width|height)\s*=\s*"[^"]+"`),
|
||||
reAttrClassPrefix: regexp.MustCompile(`(?s)\s+class\s*=\s*"`),
|
||||
}
|
||||
})
|
||||
|
||||
// Normalize normalizes the SVG content: set default width/height, remove unnecessary tags/attributes
|
||||
// It's designed to work with valid SVG content. For invalid SVG content, the returned content is not guaranteed.
|
||||
func Normalize(data []byte, size int) []byte {
|
||||
vars := globalVars()
|
||||
data = vars.reXMLDoc.ReplaceAll(data, nil)
|
||||
data = vars.reComment.ReplaceAll(data, nil)
|
||||
|
||||
data = bytes.TrimSpace(data)
|
||||
svgTag, svgRemaining, ok := bytes.Cut(data, []byte(">"))
|
||||
if !ok || !bytes.HasPrefix(svgTag, []byte(`<svg`)) {
|
||||
return data
|
||||
}
|
||||
normalized := bytes.Clone(svgTag)
|
||||
normalized = vars.reAttrXMLNs.ReplaceAll(normalized, nil)
|
||||
normalized = vars.reAttrSize.ReplaceAll(normalized, nil)
|
||||
normalized = vars.reAttrClassPrefix.ReplaceAll(normalized, []byte(` class="`))
|
||||
normalized = bytes.TrimSpace(normalized)
|
||||
normalized = fmt.Appendf(normalized, ` width="%d" height="%d"`, size, size)
|
||||
if !bytes.Contains(normalized, []byte(` class="`)) {
|
||||
normalized = append(normalized, ` class="svg"`...)
|
||||
}
|
||||
normalized = append(normalized, '>')
|
||||
normalized = append(normalized, svgRemaining...)
|
||||
return normalized
|
||||
}
|
||||
Reference in New Issue
Block a user