siyuan-note/siyuan · error
invalid package name
Error message
invalid package name
What it means
Thrown by getPackageInstallPath when bazaar.IsValidPackageName(packageName) returns false. The validator rejects names that are empty, longer than 255 chars, start/end with dot or space, contain '..', contain characters outside 0x20-0x7E, contain any of <>&'":/\|?*, or match a reserved OS name (CON, PRN, NUL, etc.). This is a path-traversal and cross-platform-safety guard referenced by GHSA-wr4w-7vjm-mmx3.
Source
Thrown at kernel/model/bazaar.go:57
Pkg *bazaar.Package
DirName string
}
// UpdatedPackage 描述本地已安装包及其在线可用更新
type UpdatedPackage struct {
Installed *bazaar.Package `json:"installed"`
Available *bazaar.Package `json:"available"`
}
func isValidPackageName(packageName string) bool {
return bazaar.IsValidPackageName(packageName)
}
func getPackageInstallPath(pkgType, packageName string) (string, string, error) {
// 校验包名必须是合法的目录名,不能包含路径分隔符或 ..,防止路径遍历
// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-wr4w-7vjm-mmx3
if !isValidPackageName(packageName) {
return "", "", errors.New("invalid package name")
}
var baseDir, jsonFileName string
switch pkgType {
case "plugins":
baseDir, jsonFileName = filepath.Join(util.DataDir, "plugins"), "plugin.json"
case "themes":
baseDir, jsonFileName = util.ThemesPath, "theme.json"
case "icons":
baseDir, jsonFileName = util.IconsPath, "icon.json"
case "templates":
baseDir, jsonFileName = filepath.Join(util.DataDir, "templates"), "template.json"
case "widgets":
baseDir, jsonFileName = filepath.Join(util.DataDir, "widgets"), "widget.json"
default:
logging.LogErrorf("invalid package type: %s", pkgType)
return "", "", errors.New("invalid package type")
}View on GitHub (pinned to 251596fc0d)
Solutions
- Pass the package name exactly as declared in its manifest (plugin.json/theme.json) — a plain directory-safe identifier.
- Strip leading/trailing whitespace and reject names with separators before calling install APIs.
- If the name comes from user input, validate it with IsValidPackageName before forwarding to the kernel.
Example fix
// before
name := userInput // "../escape"
// after
name := strings.TrimSpace(userInput)
if !bazaar.IsValidPackageName(name) {
return fmt.Errorf("invalid package name")
} Defensive patterns
Strategy: validation
Validate before calling
// Validate before any install/uninstall/size call.
if !bazaar.IsValidPackageName(packageName) {
return fmt.Errorf("invalid package name: %q", packageName)
} Type guard
func isValidPkgName(s string) bool {
return bazaar.IsValidPackageName(s)
} Prevention
- Pass package names exactly as declared in the package manifest.
- Validate user-supplied names with IsValidPackageName before forwarding to kernel APIs.
- Never construct package names from path segments or free-form input.
When it happens
Trigger: Any install/update/uninstall path-size call passing a packageName containing a path separator, '..', a Windows reserved name, or non-ASCII/special characters. Reached from InstallBazaarPackage, InstallLocalBazaarPackage, UpdateBazaarPackage, getPackageUninstallPath, and GetInstalledPackageSize.
Common situations: Malformed request from a plugin/extension sending a directory-style name, a crafted name from a malicious package manifest, or a frontend bug passing an empty/space-padded name. Also blocks any attempt to escape the package base directory.
Related errors
- marketplace package contains an invalid path
- path escapes templates dir: %s
- invalid package type
- marketplace package install path already exists
- marketplace package name mismatch: expected [%s], got [%s]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/b69e19d744f3a8ab.
Report an issue: GitHub.