Skip to content

[VFS-863] Content inside brackets in directory/file names is not decoded - #773

Merged
garydgregory merged 2 commits into
apache:masterfrom
nicktarallo:VFS-863-BracketDecoding
Jul 15, 2026
Merged

[VFS-863] Content inside brackets in directory/file names is not decoded#773
garydgregory merged 2 commits into
apache:masterfrom
nicktarallo:VFS-863-BracketDecoding

Conversation

@nicktarallo

@nicktarallo nicktarallo commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

In VFS 2.10, content inside brackets in the file URL is not decoded. This is because it is detected to be part of an IPv6 host, although this may not be desired behavior in all circumstances (local file paths that happen to have content in brackets are also affected, despite being unrelated to IPv6).

The fix here is to ensure that we only detect a host inside of the authority as defined by RFC 3986. We do this by detecting the authority as the content between the first instance of "//" and the next "/", since the URL takes the format scheme://<authority>/<path>. Brackets outside of the authority hold no special meaning, so content inside of these brackets will now be decoded.

Bug was most likely introduced by this PR

There appears to be another old, stale PR out for the same issue with a regex approach, but I could not find an associated ticket: #562

AI (Claude Code) was used to write most of the code (I reviewed all output). The fix approach and the design of the test cases were provided by me to the tool.

Only set ipv6Host to true in UriParser.decode() if it is in the
authority of the URI. Otherwise, leave it false so that content inside
of brackets in the path will still be decoded.
@nicktarallo
nicktarallo force-pushed the VFS-863-BracketDecoding branch from 90f020f to d22d69d Compare July 14, 2026 05:52
@nicktarallo nicktarallo changed the title [VFS-863] Content inside brackets in directory names is not decoded [VFS-863] Content inside brackets in directory/file names is not decoded Jul 14, 2026
@nicktarallo
nicktarallo marked this pull request as ready for review July 14, 2026 05:54
@nicktarallo

Copy link
Copy Markdown
Contributor Author

Hi @garydgregory, this was discussed briefly in the user mailing list, made a PR to try to address the issue.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an issue in Commons VFS 2.10 where percent-encoded content inside [...] in paths was not decoded because the decoder treated any bracketed section as an IPv6 host. The change narrows IPv6-host handling to bracketed content that appears within the RFC 3986 authority portion of a URI, and adds regression tests.

Changes:

  • Updated UriParser.decode(StringBuilder, ...) to only treat [...] specially when it occurs in the detected authority segment.
  • Added unit tests covering percent-decoding inside brackets in paths and preserving %25 inside IPv6 hosts.
  • Added an end-to-end local filesystem round-trip test to ensure getURL() paths containing brackets resolve consistently.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/UriParser.java Refines decode logic to avoid treating path [...] as IPv6 host unless within authority.
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/UriParserTest.java Adds focused regression tests for decoding behavior inside brackets in path vs IPv6 host.
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/local/UrlTests.java Adds round-trip integration test for local file URLs with bracketed directory names.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +170 to +175
if (ch == '/') {
consecutiveSlashes++;
if (consecutiveSlashes == 2) {
inAuthority = true;
authorityDetected = true;
}
Comment thread commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/local/UrlTests.java Outdated

@garydgregory garydgregory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hello @nicktarallo
Thank you for the PR.
Please review the comments from copilot. You might need to add a test in check the main suggestion. The test suggestion seems like a test bug.

…ter ://

Addresses review feedback:
- Authority detection previously triggered on any "//" in the input,
  so a "//" later in a path (e.g. "file:/a//[inside%25text]") would
  incorrectly treat following brackets as an IPv6 host. Detection now
  requires a leading "//" (network-path reference) or "://" with no
  earlier "/" (scheme delimiter).
- Close the Files.walk stream in UrlTests with try-with-resources.
- Add regression tests for "//" mid-path, "://" embedded in a path
  after the authority, a network-path reference IPv6 host, and a
  single URI mixing an IPv6 zone ID with brackets in the path.
@nicktarallo

Copy link
Copy Markdown
Contributor Author

Hello @nicktarallo Thank you for the PR. Please review the comments from copilot. You might need to add a test in check the main suggestion. The test suggestion seems like a test bug.

Hi @garydgregory, thanks for the review. I addressed both comments:

  • Authority detection now only triggers on a leading // (network-path reference) or on :// following the scheme. Added regression tests for the file:/a//[...] example from the review, a :// embedded in the path after the authority, and a URI mixing an IPv6 zone ID with brackets in the path.
  • Wrapped the Files.walk stream in try-with-resources.

Also verified all 4 new test methods fail against the pre-fix code.

@nicktarallo
nicktarallo requested a review from garydgregory July 15, 2026 05:27
@garydgregory
garydgregory merged commit 27ed1d2 into apache:master Jul 15, 2026
21 checks passed
@garydgregory

Copy link
Copy Markdown
Member

@nicktarallo PR merged 🚀 Thank you!

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.

3 participants