This commit is contained in:
Jeffrey Chen
2026-05-10 23:32:19 +08:00
committed by GitHub
parent 6dd37652cc
commit ff9d839c00
2 changed files with 30 additions and 10 deletions

View File

@@ -12,7 +12,7 @@ import {setStorageVal, writeText} from "../protyle/util/compatibility";
import {hasClosestByAttribute, hasClosestByClassName} from "../protyle/util/hasClosest";
import {Plugin} from "../plugin";
import {App} from "../index";
import {escapeAttr} from "../util/escape";
import {escapeAttr, escapeHtml} from "../util/escape";
import {uninstall} from "../plugin/uninstall";
import {afterLoadPlugin, loadPlugin, loadPlugins} from "../plugin/loader";
import {useShell} from "../util/pathName";
@@ -235,7 +235,10 @@ export const bazaar = {
return "";
}
try {
new URL(funding);
const url = new URL(funding);
if (!["http:", "https:", "mailto:"].includes(url.protocol)) {
throw new Error("not an allowed URL protocol");
}
return `<span class="fn__space--small"></span><a target="_blank" href="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></a>`;
} catch (e) {
return `<span class="fn__space--small"></span><span data-type="copy-funding" data-funding="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></span>`;
@@ -272,7 +275,7 @@ export const bazaar = {
</div>
<div class="fn__flex-1 fn__flex-column">
<div class="b3-card__info fn__flex-1">
${item.preferredName}
${escapeHtml(item.preferredName)}
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">
${item.preferredDesc || ""}
</div>
@@ -319,7 +322,7 @@ export const bazaar = {
<div class="b3-card__img"><img src="${item.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'"/></div>
<div class="fn__flex-1 fn__flex-column">
<div class="b3-card__info b3-card__info--left fn__flex-1">
${item.preferredName}
${escapeHtml(item.preferredName)}
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">${item.preferredDesc || ""}</div>
</div>
</div>
@@ -428,7 +431,7 @@ export const bazaar = {
<div class="b3-card__img"><img src="${item.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'"/></div>
<div class="fn__flex-1 fn__flex-column">
<div class="b3-card__info b3-card__info--left fn__flex-1">
${item.preferredName}
${escapeHtml(item.preferredName)}
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">${item.preferredDesc || ""}</div>
</div>
</div>
@@ -521,11 +524,11 @@ type="checkbox">
</div>
<img class="item__img" src="${data.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'">
<div>
<a href="${data.repoURL}" target="_blank" class="item__title" title="GitHub Repo">${data.preferredName}</a>
<a href="${data.repoURL}" target="_blank" class="item__title" title="GitHub Repo">${escapeHtml(data.preferredName)}</a>
</div>
<div class="fn__hr"></div>
<div>
<a href="${data.repoURL}" target="_blank" class="ft__on-surface ft__smaller" title="GitHub Repo">${data.name}</a>
<a href="${data.repoURL}" target="_blank" class="ft__on-surface ft__smaller" title="GitHub Repo">${escapeHtml(data.name)}</a>
</div>
<div class="block__icons">
<span class="fn__flex-1"></span>
@@ -539,7 +542,7 @@ type="checkbox">
</div>
<div class="fn__hr--b"></div>
<div class="fn__hr--b"></div>
<div class="ft__on-surface ft__smaller" style="line-height: 20px;">${window.siyuan.languages.currentVer}<br>v${data.version}</div>
<div class="ft__on-surface ft__smaller" style="line-height: 20px;">${window.siyuan.languages.currentVer}<br>v${escapeHtml(data.version)}</div>
<div class="fn__hr"></div>
<div class="ft__on-surface ft__smaller" style="line-height: 20px;">${downloaded ? window.siyuan.languages.installDate : window.siyuan.languages.releaseDate}<br>${downloaded ? data.hInstallDate : data.hUpdated}</div>
<div class="fn__hr${downloaded ? " fn__none" : ""}"></div>

View File

@@ -131,18 +131,31 @@ func ParsePackageJSON(filePath string) (ret *Package, err error) {
return
}
// sanitizePackageDisplayStrings 对集市包直接显示的信息做 HTML 转义,避免 XSS。
// sanitizePackageDisplayStrings 对集市包可能直接显示的信息做 HTML 转义,避免 XSS。
func sanitizePackageDisplayStrings(pkg *Package) {
if pkg == nil {
return
}
pkg.Name = html.EscapeString(pkg.Name)
pkg.Author = html.EscapeString(pkg.Author)
pkg.Version = html.EscapeString(pkg.Version)
for k, v := range pkg.DisplayName {
pkg.DisplayName[k] = html.EscapeString(v)
}
for k, v := range pkg.Description {
pkg.Description[k] = html.EscapeString(v)
}
if pkg.Funding != nil {
pkg.Funding.OpenCollective = html.EscapeString(pkg.Funding.OpenCollective)
pkg.Funding.Patreon = html.EscapeString(pkg.Funding.Patreon)
pkg.Funding.GitHub = html.EscapeString(pkg.Funding.GitHub)
for i, v := range pkg.Funding.Custom {
pkg.Funding.Custom[i] = html.EscapeString(v)
}
}
for i, kw := range pkg.Keywords {
pkg.Keywords[i] = html.EscapeString(kw)
}
}
// GetPreferredLocaleString 从 LocaleStrings 中按当前语种取值,无则回退 default、en_US再回退 fallback。
@@ -177,7 +190,11 @@ func getPreferredFunding(funding *Funding) string {
return v
}
if 0 < len(funding.Custom) {
return funding.Custom[0]
v := funding.Custom[0]
if strings.HasPrefix(v, "https://") || strings.HasPrefix(v, "http://") || strings.HasPrefix(v, "mailto:") {
return v
}
return ""
}
return ""
}