{"record":{"id":"c1732fbb79b64794","repo":"valyala/fasthttp","slug":"too-much-data-gunzipped-d","errorCode":null,"errorMessage":"too much data gunzipped: %d","messagePattern":"too much data gunzipped: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compress.go","lineNumber":228,"sourceCode":"}\n\n// WriteGunzip writes ungzipped p to w and returns the number of uncompressed\n// bytes written to w.\nfunc WriteGunzip(w io.Writer, p []byte) (int, error) {\n\treturn writeGunzip(w, p, 0)\n}\n\nfunc writeGunzip(w io.Writer, p []byte, maxBodySize int) (int, error) {\n\tr := &byteSliceReader{b: p}\n\tzr, err := acquireGzipReader(r)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tn, err := copyZeroAllocWithLimit(w, zr, maxBodySize)\n\treleaseGzipReader(zr)\n\tnn := int(n)\n\tif int64(nn) != n {\n\t\treturn 0, fmt.Errorf(\"too much data gunzipped: %d\", n)\n\t}\n\treturn nn, err\n}\n\n// AppendGunzipBytes appends gunzipped src to dst and returns the resulting dst.\nfunc AppendGunzipBytes(dst, src []byte) ([]byte, error) {\n\tw := &byteSliceWriter{b: dst}\n\t_, err := WriteGunzip(w, src)\n\treturn w.b, err\n}\n\n// AppendDeflateBytesLevel appends deflated src to dst using the given\n// compression level and returns the resulting dst.\n//\n// Supported compression levels are:\n//\n//   - CompressNoCompression\n//   - CompressBestSpeed","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/compress.go#L210-L246","documentation":"WriteGunzip decompresses gzip data into a writer using a bounded zero-alloc copy. If the decompressed output exceeds maxBodySize so the total cannot fit in an int, it returns 'too much data gunzipped' rather than silently truncating — a guard against decompression bombs.","triggerScenarios":"Calling fasthttp.WriteGunzip (or AppendGunzipBytes/gunzipData) with gzip input whose uncompressed size exceeds the library's maxBodySize limit.","commonSituations":"Processing user-supplied gzip payloads (a zip bomb), decompressing huge log archives into memory, proxying compressed responses without size limits.","solutions":["Stream the data with gzip.NewReader(io.LimitReader(...)) instead of one-shot decompression","Enforce a size limit on the compressed input before decompressing","Reject or truncate payloads whose declared decompressed size is too large","Use io.Copy to a file rather than an in-memory buffer for large data"],"exampleFix":"// before\nerr := fasthttp.WriteGunzip(buf, hugeGzippedBody)\n// after\nzr, err := gzip.NewReader(bytes.NewReader(hugeGzippedBody))\nif err != nil { return err }\n_, err = io.Copy(io.Discard, io.LimitReader(zr, maxDecompressed)) // bounded streaming","handlingStrategy":"validation","validationCode":"if len(gzipped) > maxCompressedInput { return errors.New(\"compressed payload too large\") }","typeGuard":null,"tryCatchPattern":"if err := fasthttp.WriteGunzip(buf, body); err != nil {\n    if strings.Contains(err.Error(), \"too much data gunzipped\") {\n        // stream to disk instead of memory\n    }\n}","preventionTips":["Cap compressed input size before decompressing","Stream untrusted gzip with io.LimitReader","Treat decompression-bomb limits as a security control, don't raise them blindly"],"tags":["go","gzip","decompression","memory-limit"],"backgroundTag":"decompression-bomb","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}