mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-09 22:18:39 +02:00
perf(citation): optimize CITATION.cff rendering (#39575)
Rendering a CITATION.cff could use memory far out of proportion to the file, as every YAML alias copies its target into the formatted citation and the parser copies `%TAG` prefixes into every node. Files past these limits show no citation, like unparseable ones do today. - Skip files over 256 KiB, largest real-world file found is 80 KiB - Skip files with `%TAG` directives - Skip files whose aliases add more than 64 Ki nodes and value bytes - Skip self-referencing anchors, except a sequence listing itself Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
1 parent
9bb8751b29
commit
2705abf7f3
4 files changed
+85
-19
No files matched your search
@@ -22,7 +22,6 @@ import (
|
||||
"gitea.dev/modules/git"
|
||||
"gitea.dev/modules/htmlutil"
|
||||
"gitea.dev/modules/httplib"
|
||||
"gitea.dev/modules/lfs"
|
||||
"gitea.dev/modules/log"
|
||||
repo_module "gitea.dev/modules/repository"
|
||||
"gitea.dev/modules/setting"
|
||||
@@ -102,33 +101,36 @@ func prepareHomeSidebarCitationFile(ctx *context.Context) {
|
||||
ctx.ServerError("ListEntries", err)
|
||||
return
|
||||
}
|
||||
isBlob := func(entry *git.TreeEntry) bool { return !entry.IsDir() && !entry.IsSubModule() }
|
||||
for _, name := range []string{"CITATION.cff", "CITATION.bib"} {
|
||||
idx := slices.IndexFunc(allEntries, func(entry *git.TreeEntry) bool { return isBlob(entry) && strings.EqualFold(entry.Name(), name) })
|
||||
isBlobSupported := func(entry *git.TreeEntry) bool {
|
||||
return entry.IsRegular() || entry.IsExecutable() || entry.IsLink()
|
||||
}
|
||||
const nameCff = "CITATION.cff"
|
||||
const nameBib = "CITATION.bib"
|
||||
for _, name := range []string{nameCff, nameBib} {
|
||||
idx := slices.IndexFunc(allEntries, func(entry *git.TreeEntry) bool {
|
||||
return isBlobSupported(entry) && util.AsciiEqualFold(entry.Name(), name)
|
||||
})
|
||||
if idx == -1 {
|
||||
continue
|
||||
}
|
||||
entry := allEntries[idx]
|
||||
if entry.IsLink() {
|
||||
res, err := git.EntryFollowLinks(ctx, ctx.Repo.GitRepo, ctx.Repo.Commit, entry.Name(), entry)
|
||||
if err != nil || !isBlob(res.TargetEntry) {
|
||||
if err != nil || !isBlobSupported(res.TargetEntry) {
|
||||
continue
|
||||
}
|
||||
entry = res.TargetEntry
|
||||
}
|
||||
content, err := entry.Blob(ctx.Repo.GitRepo).GetBlobContent(ctx, setting.UI.MaxDisplayFileSize)
|
||||
content, err := entry.Blob(ctx.Repo.GitRepo).GetBlobContent(ctx, citation.MaxContentSize+1)
|
||||
if err != nil {
|
||||
log.Error("prepareHomeSidebarCitationFile: GetBlobContent: %v", err)
|
||||
continue
|
||||
}
|
||||
if pointer, _ := lfs.ReadPointerFromBuffer([]byte(content)); pointer.IsValid() {
|
||||
continue
|
||||
}
|
||||
apa, bibtex := "", content
|
||||
if name == "CITATION.cff" {
|
||||
if name == nameCff {
|
||||
apa, bibtex = citation.FormatCFF(content)
|
||||
}
|
||||
if bibtex != "" {
|
||||
if citation.IsLikelyBibTeX(bibtex) {
|
||||
ctx.Data["CitationFileName"] = allEntries[idx].Name()
|
||||
ctx.Data["CitationAPA"] = apa
|
||||
ctx.Data["CitationBibTeX"] = bibtex
|
||||
|
||||
Reference in new issue
Block a user