{"record":{"id":"cf049a432ca3e00a","repo":"siyuan-note/siyuan","slug":"marketplace-package-is-too-large","errorCode":null,"errorMessage":"marketplace package is too large","messagePattern":"marketplace package is too large","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/local.go","lineNumber":109,"sourceCode":"\tif err != nil {\n\t\treturn errors.New(\"invalid marketplace package archive\")\n\t}\n\tdefer reader.Close()\n\n\tif len(reader.File) == 0 {\n\t\treturn errors.New(\"marketplace package archive is empty\")\n\t}\n\tif len(reader.File) > maxLocalPackageFileCount {\n\t\treturn errors.New(\"marketplace package contains too many files\")\n\t}\n\n\tvar declaredTotal uint64\n\tfor _, item := range reader.File {\n\t\tif item.UncompressedSize64 > maxLocalPackageFileSize {\n\t\t\treturn errors.New(\"marketplace package contains a file that is too large\")\n\t\t}\n\t\tif ^uint64(0)-declaredTotal < item.UncompressedSize64 {\n\t\t\treturn errors.New(\"marketplace package is too large\")\n\t\t}\n\t\tdeclaredTotal += item.UncompressedSize64\n\t\tif declaredTotal > maxLocalPackageExtractSize {\n\t\t\treturn errors.New(\"marketplace package is too large\")\n\t\t}\n\t}\n\n\tif err = os.MkdirAll(destination, 0755); err != nil {\n\t\treturn err\n\t}\n\tvar extractedTotal uint64\n\tfor _, item := range reader.File {\n\t\tif err = extractLocalPackageItem(item, destination, &extractedTotal); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/bazaar/local.go#L91-L127","documentation":"Integer-overflow guard: adding the current entry's declared UncompressedSize64 to the running declaredTotal would exceed uint64 max (^uint64(0)). Thrown by extractLocalPackageArchive (kernel/bazaar/local.go:108-109) before the addition. This is purely a defense against crafted headers with spoofed near-UINT64_MAX sizes; no legitimate archive reaches it.","triggerScenarios":"A zip entry header advertises an uncompressed size so large that summing it into the uint64 accumulator would wrap around. This only occurs with deliberately malformed/crafted archives, never with real packages.","commonSituations":"A malicious archive submitted to the local-package install endpoint in an attempt to overflow the size accumulator and bypass the total-size check that follows.","solutions":["Reject the archive at the trust boundary (upload handler) — it is not a legitimate package","Re-download or rebuild the package from a trusted source","If auditing, flag the submitter; this signal indicates a crafted zip-bomb probe"],"exampleFix":"// before: accepting untrusted archives straight into ExtractLocalPackage\npkgType, pkg, src, cleanup, err := bazaar.ExtractLocalPackage(uploadedPath)\n\n// after: validate declared sizes first and refuse absurd headers\nif ok, err := precheckZipSizes(uploadedPath); !ok || err != nil {\n    return fmt.Errorf(\"rejecting suspicious archive: %v\", err)\n}","handlingStrategy":"validation","validationCode":"func assertNoOverflow(path string) error {\n    r, err := zip.OpenReader(path)\n    if err != nil { return err }\n    defer r.Close()\n    var total uint64\n    for _, f := range r.File {\n        if ^uint64(0)-total < f.UncompressedSize64 {\n            return fmt.Errorf(\"entry %q declared size overflows accumulator\", f.Name)\n        }\n        total += f.UncompressedSize64\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Hostile-input signal: do not retry, reject outright\nif err != nil { return fmt.Errorf(\"rejecting suspicious archive: %w\", err) }","preventionTips":["Treat a header-overflow trip as malicious until proven otherwise","Validate declared sizes at the upload trust boundary, before disk extraction","Log submitter/IP when this guard fires for incident review"],"tags":["zip","archive","bazaar","zip-bomb","security","integer-overflow"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}