{"record":{"id":"c0c10992193f7c8b","repo":"siyuan-note/siyuan","slug":"invalid-bazaar-rating-region","errorCode":null,"errorMessage":"invalid bazaar rating region","messagePattern":"invalid bazaar rating region","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/rating.go","lineNumber":409,"sourceCode":"\tcache.mu.RLock()\n\tdefer cache.mu.RUnlock()\n\tret.loaded = cache.loaded\n\tfresh = cache.loaded && now.Before(cache.expiresAt)\n\tif !cache.loaded {\n\t\treturn\n\t}\n\tret.data = cloneBazaarRatingDistributions(cache.data)\n\tfor packageName, override := range cache.overrides {\n\t\tif now.Before(override.expiresAt) {\n\t\t\tret.data[packageName] = override.distribution\n\t\t}\n\t}\n\treturn\n}\n\nfunc fetchBazaarRatingRegion(ctx context.Context, region int) (ret map[string]bazaarRatingDistribution, err error) {\n\tif region < 0 || bazaarRatingRegionCount <= region {\n\t\treturn nil, errors.New(\"invalid bazaar rating region\")\n\t}\n\n\ttimeBucket := bazaarRatingNow().Unix() / int64(bazaarRatingCDNBucket/time.Second)\n\tu := fmt.Sprintf(\"%s/bazaar/ratings/v1/%s?t=%d\", bazaarRatingStatServer, bazaarRatingRegionFiles[region], timeBucket)\n\tbuf := &bytes.Buffer{}\n\tresp, err := httpclient.NewBrowserRequest().SetRetryCount(0).SetContext(ctx).SetOutput(buf).Get(u)\n\tif nil != err {\n\t\treturn nil, err\n\t}\n\tif 200 != resp.StatusCode {\n\t\treturn nil, fmt.Errorf(\"unexpected status code: %d\", resp.StatusCode)\n\t}\n\n\tret, err = parseBazaarRatingRegion(buf.Bytes())\n\treturn\n}\n\nfunc parseBazaarRatingRegion(data []byte) (ret map[string]bazaarRatingDistribution, err error) {","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/bazaar/rating.go#L391-L427","documentation":"Thrown by fetchBazaarRatingRegion when the requested marketplace rating region index is negative or >= bazaarRatingRegionCount. Regions index into bazaarRatingRegionFiles, whose length defines the valid range, so an out-of-range index has no corresponding rating data file.","triggerScenarios":"Calling fetchBazaarRatingRegion (exposed for testing via TestFetchBazaarRatingRegion) with region < 0 or region >= the number of entries in bazaarRatingRegionFiles. Any code path computing a region index from user input or config can pass an invalid value.","commonSituations":"A test or caller hardcoding a region index beyond the number of region files after the file list changed; computing the index with an off-by-one (using length instead of length-1); parsing a user-supplied region number without bounds checking.","solutions":["Clamp or validate the region index against bazaarRatingRegionCount before calling: 0 <= region < bazaarRatingRegionCount.","If the index comes from user input or config, parse and bounds-check it, defaulting to a valid region on error.","If region files were added or removed, update callers so their indices match the new bazaarRatingRegionFiles list.","Fix off-by-one loops to use region < bazaarRatingRegionCount, not <=."],"exampleFix":"// before\nfetchBazaarRatingRegion(ctx, 5) // hardcoded, out of range\n// after\nif region < 0 || region >= bazaarRatingRegionCount {\n    region = 0 // or return a validation error upstream\n}\nfetchBazaarRatingRegion(ctx, region)","handlingStrategy":"validation","validationCode":"// Go: bounds-check the region before fetching\nfunc validRegion(r int) bool { return r >= 0 && r < bazaarRatingRegionCount }","typeGuard":null,"tryCatchPattern":"if dists, err := fetchBazaarRatingRegion(ctx, region); err != nil {\n    if strings.Contains(err.Error(), \"invalid bazaar rating region\") {\n        return errors.New(\"region index out of range; must be 0 <= region < bazaarRatingRegionCount\")\n    }\n    return err\n}","preventionTips":["Derive region indices from len(bazaarRatingRegionFiles)-1, never hardcode numbers","Validate user/config-supplied region numbers before calling","Re-check callers whenever the region file list changes"],"tags":["bazaar","region","bounds-check","invalid-index"],"backgroundTag":"argument-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"}