{"record":{"id":"b21429a95a13ffb1","repo":"siyuan-note/siyuan","slug":"bazaar-downloads-overflow-s","errorCode":null,"errorMessage":"bazaar downloads overflow: %s","messagePattern":"bazaar downloads overflow: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/index.go","lineNumber":268,"sourceCode":"\tif !hasMeta || 2 == ret.meta.Schema || bazaarIndexSchema < ret.meta.Schema {\n\t\tfor rawRepo, rawStats := range raw {\n\t\t\tif \"meta\" == rawRepo || \"packages\" == rawRepo {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trepo, valid := normalizeLegacyBazaarRepo(rawRepo)\n\t\t\tif !valid {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid bazaar repository: %s\", rawRepo)\n\t\t\t}\n\t\t\tstats := &bazaarStats{}\n\t\t\tif err = json.Unmarshal(rawStats, stats); nil != err {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif 0 > stats.Downloads {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid bazaar downloads: %s\", rawRepo)\n\t\t\t}\n\t\t\tif current := ret.legacyStats[repo]; nil != current {\n\t\t\t\tif stats.Downloads > int(^uint(0)>>1)-current.Downloads {\n\t\t\t\t\treturn nil, fmt.Errorf(\"bazaar downloads overflow: %s\", repo)\n\t\t\t\t}\n\t\t\t\tcurrent.Downloads += stats.Downloads\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tret.legacyStats[repo] = stats\n\t\t}\n\t}\n\treturn\n}\n\nfunc normalizeLegacyBazaarRepo(repo string) (string, bool) {\n\tconst githubPrefix = \"https://github.com/\"\n\tif strings.HasPrefix(repo, githubPrefix) {\n\t\trepo = strings.TrimPrefix(repo, githubPrefix)\n\t}\n\tif !isValidBazaarRepo(repo) {\n\t\treturn \"\", false\n\t}","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/bazaar/index.go#L250-L286","documentation":"When the same repository appears under multiple (case/prefix-variant) keys in a legacy index, downloads are summed into one entry. parseBazaarIndex throws this guard when adding a new count would overflow int (the platform's max int), preventing wraparound.","triggerScenarios":"An index JSON lists the same repo under two normalized-equal keys whose combined downloads exceed int(^uint(0)>>1) (max int64 on 64-bit); the second occurrence's addition is checked and rejected.","commonSituations":"Essentially only adversarial or fabricated index data — a malicious or buggy mirror emitting astronomically large download counts to trigger overflow; real totals never reach max int64.","solutions":["Treat this as untrusted/tampered index data: re-fetch from the official bazaar stat server and verify contents","If operating a mirror, sanity-limit downloads values to plausible ranges before serving","Inspect the named repo's entries in the JSON and correct the inflated counts"],"exampleFix":"// before\n{\"u/r\": {\"downloads\": 9223372036854775807}, \"U/R\": {\"downloads\": 5}}\n// after\n{\"u/r\": {\"downloads\": 9223372036854775802}}","handlingStrategy":"validation","validationCode":"// normalize repo keys first and reject implausible totals\nif stats.Downloads > 1_000_000_000 {\n\treturn fmt.Errorf(\"implausible downloads for %s\", repo)\n}","typeGuard":null,"tryCatchPattern":"snapshot, err := parseBazaarIndex(data)\nif err != nil {\n\tif strings.HasPrefix(err.Error(), \"bazaar downloads overflow:\") {\n\t\tlog.Errorf(\"suspected tampered index (int overflow); discard and refetch\")\n\t}\n\treturn err\n}","preventionTips":["Treat overflow as tampered data and refetch from the official server","Sanity-limit downloads values in any mirror you operate","Keep duplicate repo variants (case/prefix) merged server-side","Avoid fabricating index JSON with maximal int values in tests"],"tags":["bazaar","marketplace","overflow","integer","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}