Skip to content

Validate path components#1959

Merged
cstamas merged 2 commits into
apache:masterfrom
cstamas:validate-path-components
Jul 14, 2026
Merged

Validate path components#1959
cstamas merged 2 commits into
apache:masterfrom
cstamas:validate-path-components

Conversation

@cstamas

@cstamas cstamas commented Jul 13, 2026

Copy link
Copy Markdown
Member

But make it reusable as well. When 2.0.21 released, Maven codebase of DefaultVersionResolver and DefaultVersionRangeResolver should be updated too, and use this util method.

Supersedes (and based on) #1958

But make it reusable as well.

Supersedes apache#1958
@cstamas
cstamas marked this pull request as ready for review July 13, 2026 16:36

@gnodet gnodet 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.

AI-Assisted Review — PR #1959 (Validate path components)

The core contribution here — extracting path traversal validation into PathUtils for cross-project reuse and applying it at the DefaultLocalPathComposer boundary — is well-designed and correct. The equals("..") + contains("/") + contains("\\") approach is sound and more precise than PR #1958's contains(".."), with the reasoning properly documented in code comments ("version '1..' is valid").

Verified concern: GenericVersion constructor validation

The addition of validatePathComponent inside the GenericVersion constructor conflates filesystem-safety with version parsing. GenericVersion is a pure version-parsing/comparison class used for version ranges, dependency resolution ordering, constraint evaluation, and version comparison — none of which involve filesystem paths.

The IllegalArgumentException escapes through parseVersion() uncaught. The call chain:

  1. GenericVersionScheme.parseVersion(String) declares throws InvalidVersionSpecificationException (checked)
  2. It calls new GenericVersion(version)validatePathComponent() → throws IllegalArgumentException (unchecked)
  3. Callers like AbstractPatternDependencyFilter.isVersionIncludedInRange() catch only InvalidVersionSpecificationException — the unchecked exception propagates unhandled

This is a behavioral change to a widely-used public API. Any downstream code using parseVersion() with a version string containing / or \ (unusual but not currently invalid) would get an uncaught IllegalArgumentException instead of a successful Version object.

Suggestion

Consider keeping the PathUtils extraction and DefaultLocalPathComposer integration (which is the right enforcement point — where versions become filesystem path segments), but removing the GenericVersion constructor change. If version-level validation is desired as defense-in-depth, it could either:

  • Throw InvalidVersionSpecificationException instead (if path traversal is considered a version syntax violation), or
  • Be applied at a different layer (e.g., in Maven's DefaultVersionResolver)

Other notes

  • The metadata type exclusion from validation is correctly documented (.meta/prefixes.txt contains legitimate path separators)
  • This PR completely supersedes PR #1958 — if merged, #1958 should be closed
  • Test coverage for the core path validation through DefaultLocalPathComposerTest is solid; direct unit tests for PathUtils.validatePathComponent and the GenericVersion constructor behavior would strengthen coverage

🤖 This review was generated with AI assistance (reviewer + independent verifier pattern). Findings were independently verified before posting.

gnodet added a commit to gnodet/maven-resolver that referenced this pull request Jul 13, 2026
gnodet added a commit to gnodet/maven-resolver that referenced this pull request Jul 13, 2026
gnodet added a commit to gnodet/maven-resolver that referenced this pull request Jul 13, 2026
@cstamas

cstamas commented Jul 13, 2026

Copy link
Copy Markdown
Member Author

Agreed with assessment: will remove validatePathComponent from GenericVersion ctor, and it should really go into Maven stuff.

@gnodet

gnodet commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Thanks for the quick update, @cstamas! Removing the validatePathComponent from the GenericVersion constructor looks right — this keeps the validation at the path-composition layer where it belongs, without affecting version parsing semantics. The remaining changes (PathUtils extraction + DefaultLocalPathComposer validation) look good.

@cstamas cstamas added this to the 2.0.21 milestone Jul 14, 2026
@cstamas
cstamas merged commit ffcf153 into apache:master Jul 14, 2026
14 checks passed
@cstamas
cstamas deleted the validate-path-components branch July 14, 2026 20:03
@github-actions

Copy link
Copy Markdown

@cstamas Please assign appropriate label to PR according to the type of change.

@cstamas cstamas added the bug Something isn't working label Jul 14, 2026
// OTOH: version "1.." is valid version string!
if (value.equals("..") || value.contains("/") || value.contains("\\")) {
throw new IllegalArgumentException(
"Invalid " + label + ": must not contain '..', '/' or '\\': " + value);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should maybe be:
"Invalid " + label + ": must not be equal to '..' or contain '/' or '\': " + value);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants