Repository navigation
fix(raw): escape path segments when building raw content URLs - #3615
Open
sarankumar1325 wants to merge 1 commit into
Open
sarankumar1325 wants to merge 1 commit into
sarankumar1325 wants to merge 1 commit into
Conversation
repo:// resource reads pass the decoded file path to url.URL.JoinPath, which treats its arguments as already escaped. A file named %41.txt was fetched as A.txt, and an invalid escape such as 100%.txt made JoinPath fall back to the bare base URL, so the resource returned GitHub's homepage HTML. PathEscape each /-separated segment of owner, repo, ref and path before joining. Fixes github#3614
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
repo://resource reads now percent-encode each path segment before building the raw.githubusercontent.com URL, so file names containing%are fetched exactly as named.Why
Fixes #3614
raw.Clientpassed the decoded owner/repo/ref/path tourl.URL.JoinPath, which treats its arguments as already escaped.%41.txtwas fetched asA.txt, and100%.txt(an invalid escape) madeJoinPathquietly fall back to the base URL, so the resource returned GitHub's homepage HTML as the file content.What changed
pkg/raw/raw.go: newescapePathSegmentshelper appliesurl.PathEscapeto every/-separated segment of owner, repo, ref/sha and path beforeJoinPathinrefURLandcommitURL. The existing..traversal rejection runs first and is unchanged.pkg/raw/raw_test.go: cases fordocs/100%.txt,%41.txt,%with a SHA, and space/#/?/unicode in a ref and path. The oldbenign percent-encoded filename allowedcase expected%2ehiddento go out unescaped, which actually requested.hidden. It now expects%252ehidden.pkg/github/repository_resource_test.go: handler-level test thatrepo://owner/repo/contents/docs/100%25.txtand.../%2541.txtrequest/owner/repo/HEAD/docs/100%.txtand/owner/repo/HEAD/%41.txt. Both fail onmain(one errors, one requestsA.txt).MCP impact
Prompts tested (tool changes only)
Security / limits
rejectPathTraversal) still run on the unescaped input before escaping, and escaping means an encoded..can no longer be decoded byJoinPath.Tool renaming
deprecated_tool_aliases.goLint & tests
./script/lint(gofmt -s and golangci-lint v2.14.0: 0 issues)./script/test(go test ./...passes)Docs
I used an AI assistant to write this change. I reviewed the diff and ran the tests above.