Skip to content

Proxy: Fix resource leak in ParseBody. v8.0.26 - #4659

Merged
winlinvip merged 5 commits into
ossrs:developfrom
sevico:fix/utils-nil-pointer-and-resource-leak
Aug 18, 2026
Merged

Proxy: Fix resource leak in ParseBody. v8.0.26#4659
winlinvip merged 5 commits into
ossrs:developfrom
sevico:fix/utils-nil-pointer-and-resource-leak

Conversation

@sevico

@sevico sevico commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Problem

ParseBody in internal/utils/utils.go defers r.Close() only after io.ReadAll(r) succeeds. If io.ReadAll returns an error, the function returns before registering the deferred close, so the request/body reader is left open.

func ParseBody(r io.ReadCloser, v interface{}) error {
    b, err := io.ReadAll(r)
    if err != nil {
        return errors.Wrapf(err, "read body") // r is not closed on this path
    }
    defer r.Close()

Solution

Move defer r.Close() to the top of ParseBody, before reading the body, so all return paths close the reader.

func ParseBody(r io.ReadCloser, v interface{}) error {
    defer r.Close()

    b, err := io.ReadAll(r)

@winlinvip winlinvip added the EnglishNative This issue is conveyed exclusively in English. label Apr 11, 2026
@winlinvip
winlinvip force-pushed the develop branch 3 times, most recently from 6ce415e to 6ee6f1c Compare May 17, 2026 16:09
…arseBody

1. BuildStreamURL: net.ParseIP() returns nil for non-IP hostnames
   (e.g., "example.com"), then calling nil.To4() panics. Add nil
   check before calling To4().

2. ParseBody: defer r.Close() is placed after the ReadAll error
   check. If ReadAll fails, the function returns early without
   closing r, causing a resource leak. Move defer to the top of
   the function.
@suzp1984
suzp1984 force-pushed the fix/utils-nil-pointer-and-resource-leak branch from b9d182c to e124f9f Compare May 19, 2026 03:19
@suzp1984

Copy link
Copy Markdown
Contributor

I rebased your branch to develop branch.
And this commit make sense.

Add TestParseBody_CloseCalledOnReadError to verify r.Close() is called
even when ReadAll fails (resource leak fix).

Enhance TestBuildStreamURL with:
- Comment explaining the example.com case would panic before the nil
  pointer fix (net.ParseIP returns nil for non-IP hostnames)
- IPv6 test cases to verify ip.To4() check works correctly
- Clarifying comments for each test case category
@suzp1984

Copy link
Copy Markdown
Contributor

One more thing, I added UT to cover this PR.

@winlinvip winlinvip changed the title Proxy: Fix nil pointer panic in BuildStreamURL and resource leak in ParseBody Proxy: Fix resource leak in ParseBody Aug 18, 2026
@winlinvip winlinvip changed the title Proxy: Fix resource leak in ParseBody Proxy: Fix resource leak in ParseBody. v8.0.25 Aug 18, 2026
@winlinvip winlinvip changed the title Proxy: Fix resource leak in ParseBody. v8.0.25 Proxy: Fix resource leak in ParseBody. v8.0.26 Aug 18, 2026
@winlinvip
winlinvip merged commit 69cbfe5 into ossrs:develop Aug 18, 2026
12 checks passed
winlinvip added a commit that referenced this pull request Aug 18, 2026
Backports #4659 (`69cbfe5e9`) to the SRS 7.0 release branch.

`ParseBody` deferred `r.Close()` only after `io.ReadAll(r)` succeeded.
When `io.ReadAll` returned an error, the function returned before
registering the deferred close, leaving the request/body reader open.

---

Co-authored-by: sevico <swkhack@gmail.com>
Co-authored-by: Jacob Su <suzp1984@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

EnglishNative This issue is conveyed exclusively in English.

Development

Successfully merging this pull request may close these issues.

3 participants