siyuan-note/siyuan · error

marketplace package is too large

Error message

marketplace package is too large

What it means

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.

Source

Thrown at kernel/bazaar/local.go:109

	if err != nil {
		return errors.New("invalid marketplace package archive")
	}
	defer reader.Close()

	if len(reader.File) == 0 {
		return errors.New("marketplace package archive is empty")
	}
	if len(reader.File) > maxLocalPackageFileCount {
		return errors.New("marketplace package contains too many files")
	}

	var declaredTotal uint64
	for _, item := range reader.File {
		if item.UncompressedSize64 > maxLocalPackageFileSize {
			return errors.New("marketplace package contains a file that is too large")
		}
		if ^uint64(0)-declaredTotal < item.UncompressedSize64 {
			return errors.New("marketplace package is too large")
		}
		declaredTotal += item.UncompressedSize64
		if declaredTotal > maxLocalPackageExtractSize {
			return errors.New("marketplace package is too large")
		}
	}

	if err = os.MkdirAll(destination, 0755); err != nil {
		return err
	}
	var extractedTotal uint64
	for _, item := range reader.File {
		if err = extractLocalPackageItem(item, destination, &extractedTotal); err != nil {
			return err
		}
	}
	return nil
}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Reject the archive at the trust boundary (upload handler) — it is not a legitimate package
  2. Re-download or rebuild the package from a trusted source
  3. If auditing, flag the submitter; this signal indicates a crafted zip-bomb probe

Example fix

// before: accepting untrusted archives straight into ExtractLocalPackage
pkgType, pkg, src, cleanup, err := bazaar.ExtractLocalPackage(uploadedPath)

// after: validate declared sizes first and refuse absurd headers
if ok, err := precheckZipSizes(uploadedPath); !ok || err != nil {
    return fmt.Errorf("rejecting suspicious archive: %v", err)
}
Defensive patterns

Strategy: validation

Validate before calling

func assertNoOverflow(path string) error {
    r, err := zip.OpenReader(path)
    if err != nil { return err }
    defer r.Close()
    var total uint64
    for _, f := range r.File {
        if ^uint64(0)-total < f.UncompressedSize64 {
            return fmt.Errorf("entry %q declared size overflows accumulator", f.Name)
        }
        total += f.UncompressedSize64
    }
    return nil
}

Try / catch

// Hostile-input signal: do not retry, reject outright
if err != nil { return fmt.Errorf("rejecting suspicious archive: %w", err) }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/cf049a432ca3e00a. Report an issue: GitHub.