Skip to content

fix: clone byte slices in NewReusableReadCloser to avoid sharing caller memory (fixes #795) - #797

Merged
Mzack9999 merged 2 commits into
projectdiscovery:mainfrom
TassioSales:fix/reusable-read-closer-copy-slice
Oct 23, 2026
Merged

Mzack9999 merged 2 commits into
projectdiscovery:mainfrom
TassioSales:fix/reusable-read-closer-copy-slice

Conversation

@TassioSales

Copy link
Copy Markdown
Contributor

Closes #795

Summary

When NewReusableReadCloser was constructed with []byte, *[]byte, or *bytes.Buffer, it wrapped the caller's slice directly without copying (
eadBuf = *bytes.NewBuffer(body)).
Upon reaching EOF,
eset() calls io.Copy(r.readBuf, r.backBuf), writing the buffer back into
eadBuf and mutating the caller's underlying slice. Consequently:

  • Any later modification to the caller's slice corrupted the reader.
  • Readers constructed from the same slice overwrote each other's memory during reset (affecting callers such as
    etryablehttp's request retries and dumps, as reported in NewReusableReadCloser shares the caller's byte slice #795 and nuclei#7878).

Changes

  • Updated NewReusableReadCloser to clone the byte slice using �ytes.Clone(...) for []byte, *[]byte, and *bytes.Buffer.
  • Added defensive nil checks for *[]byte and *bytes.Buffer.
  • Added unit tests in
    eader/reusable_read_closer_test.go verifying slice isolation across caller mutations, multiple readers from the same slice, and nil pointers.

…er memory

- Use bytes.Clone for []byte, *[]byte, and *bytes.Buffer to prevent mutating caller slices during reset
- Fixes projectdiscovery#795
- Add unit tests verifying slice isolation across mutations, multiple readers, and nil pointers
@TassioSales
TassioSales force-pushed the fix/reusable-read-closer-copy-slice branch from 5f2a885 to 18634e3 Compare October 21, 2026 00:32
@Mzack9999
Mzack9999 merged commit 0525676 into projectdiscovery:main Oct 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NewReusableReadCloser shares the caller's byte slice

2 participants