{"record":{"id":"9bcc967426ea3f66","repo":"siyuan-note/siyuan","slug":"marketplace-package-name-mismatch-expected-s","errorCode":null,"errorMessage":"marketplace package name mismatch: expected [%s], got [%s]","messagePattern":"marketplace package name mismatch: expected \\[(.+?)\\], got \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/install.go","lineNumber":182,"sourceCode":"\t}\n\n\tsrcPath := unzipPath\n\tif 1 == len(dirs) && dirs[0].IsDir() {\n\t\tsrcPath = filepath.Join(unzipPath, dirs[0].Name())\n\t}\n\n\t// 校验下载包自身声明的名称与请求安装的包名一致，防止把其他包的内容写入指定目录\n\t// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-rpx2-p6hp-x5gj\n\tjsonFileName, ok := packageManifestNames[pkgType]\n\tif !ok {\n\t\treturn errors.New(\"invalid marketplace package type\")\n\t}\n\tpkg, parseErr := ParsePackageJSON(filepath.Join(srcPath, jsonFileName))\n\tif parseErr != nil || nil == pkg {\n\t\treturn errors.New(\"marketplace package manifest not found or invalid\")\n\t}\n\tif packageName != pkg.Name {\n\t\treturn fmt.Errorf(\"marketplace package name mismatch: expected [%s], got [%s]\", packageName, pkg.Name)\n\t}\n\n\tif err = replacePackageDirectory(srcPath, installPath, update); err != nil {\n\t\treturn\n\t}\n\treturn\n}\n\n// replacePackageDirectory 将 sourcePath 整目录替换到 installPath。\n// 先拷到安装目录同级的 staging，更新时再把旧目录 rename 成 backup，最后把 staging rename 成目标路径。\n// 这样新包已删除的文件不会残留，失败时也可以把 backup rename 回去。\nfunc replacePackageDirectory(sourcePath, installPath string, update bool) (err error) {\n\tpackageInstallLock.Lock()\n\tdefer packageInstallLock.Unlock()\n\n\tif err = os.MkdirAll(filepath.Dir(installPath), 0755); err != nil {\n\t\treturn\n\t}","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/bazaar/install.go#L164-L200","documentation":"As a path-traversal / supply-chain safeguard (GHSA-rpx2-p6hp-x5gj), installPackage compares the `name` declared in the downloaded package's own manifest against the package name requested for installation. Any mismatch aborts the install so one package's contents can never be written into another package's directory.","triggerScenarios":"Downloading package A but its manifest declares name B — e.g. the index URL for pkgName points at a different package's archive, or the author renamed the package without updating the manifest.","commonSituations":"Tampered or misconfigured marketplace index entries; author forgot to bump `name` in plugin.json after a rename; malicious archives crafted to overwrite arbitrary install dirs; stale caches pairing names with wrong URLs.","solutions":["Fix the package manifest `name` to match the marketplace-published package name and re-release","Refresh the marketplace index / clear caches so the URL matches the package name","If installing locally, pass the correct package name that the manifest declares"],"exampleFix":"// before: plugin.json name \"old-name\", installed as \"new-name\"\n// after: set plugin.json name to \"new-name\" and republish","handlingStrategy":"validation","validationCode":"pkg, err := bazaar.ParsePackageJSON(\"plugin.json\")\nif err != nil || pkg.Name != expectedName {\n    return fmt.Errorf(\"archive name %q does not match requested %q\", pkg.Name, expectedName)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the manifest `name` in sync with the marketplace package name on every rename","Fetch package URLs only from a trusted, current index","Never install from ad-hoc URLs outside the marketplace flow (the name check is a supply-chain guard)"],"tags":["bazaar","security","manifest","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}