Skip to content

vendor: github.com/moby/moby/client v0.6.1, moby/api v1.56.1 - #7348

Merged
thaJeztah merged 1 commit into
docker:masterfrom
thaJeztah:bump_client
Oct 1, 2026
Merged

thaJeztah merged 1 commit into
docker:masterfrom
thaJeztah:bump_client

Conversation

@thaJeztah

Copy link
Copy Markdown
Member

Summary

Release notes (optional)

A picture of a cute animal (not mandatory but encouraged)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟡 NEEDS ATTENTION

}

if len(t.respHooks) > 0 {
hookResp := *resp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[medium] Shallow copy of http.Response shares Header map with hooks

At line 51, hookResp := *resp is a struct shallow-copy. Because http.Header is map[string][]string (a reference type), hookResp.Header and resp.Header point to the same underlying map. Any response hook that modifies headers (adds, removes, or mutates values) will silently mutate the response that gets returned to the caller — even though the intent is clearly to give hooks a sandboxed view of the response (the explicit hookResp.Body = hookBody{} guard on the very next line shows this intent for the body).

The asymmetry is stark: the request-hook path uses req.Clone() which does a proper deep copy of headers, but the response-hook path skips the equivalent step. The ResponseHook type docs only forbid reading/closing the body — header mutation is not prohibited, so hook authors writing header-inspecting/modifying hooks would have no warning of this bleed-through.

Suggested change
hookResp := *resp
hookResp := *resp
hookResp.Header = resp.Header.Clone()
Confidence Score
🟢 strong 100/100

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟢 APPROVE

}

if len(t.respHooks) > 0 {
hookResp := *resp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] Response hooks receive a shallow copy; scalar field mutations are silently discarded

hookTransport.RoundTrip creates a shallow copy of the response (hookResp := *resp), stubs out the body on the copy to prevent hooks from reading it, and then passes &hookResp to each ResponseHook. However, after the hooks run, the original resp is returned to the caller — not &hookResp. This means:

  • Header mutations (Add/Set/Del) propagate correctly because http.Header is a map[string][]string (reference type) — the shallow copy shares the same underlying map.
  • Scalar field mutations (StatusCode, Status, Proto, ContentLength, etc.) are silently lost because those are value-copied.

This creates an inconsistent API contract: header mutations work, but status-code mutations don't. The analogous request-hook path explicitly propagates mutations via req = hookReq before passing to the transport. The response path has no equivalent.

If ResponseHook is intended as a read-only observation hook (for logging/tracing), the docs should state "hooks must not mutate the response" explicitly to avoid surprising callers. If mutation is intended, scalar fields should be copied back to resp after the hooks run (or resp itself should be passed directly, with body stubbing applied there).

Confidence Score
🟡 moderate 70/100

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contact is for hooks to not make modifications; the shallow copy exists so hooks can access response metadata while being unable to consume/close the actual body. It wasn't introduced as a general sandbox for arbitrary mutations.

@thaJeztah
thaJeztah merged commit e3559d2 into docker:master Oct 1, 2026
107 checks passed
@thaJeztah
thaJeztah deleted the bump_client branch October 1, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants