Skip to content

Validate coordinates and repository precedence during artifact resolution - #12955

Open
slachiewicz wants to merge 7 commits into
apache:maven-3.9.xfrom
slachiewicz:pr/artifact-resolution-3.9.x
Open

Validate coordinates and repository precedence during artifact resolution#12955
slachiewicz wants to merge 7 commits into
apache:maven-3.9.xfrom
slachiewicz:pr/artifact-resolution-3.9.x

Conversation

@slachiewicz

@slachiewicz slachiewicz commented Aug 30, 2026

Copy link
Copy Markdown
Member

Coordinates and repository lists arriving from a resolved artifact descriptor are validated before use.

  • Repository precedence. Repositories declared by a resolved model no longer replace a same-id repository supplied by the request or session. A repository the model itself declared is still refreshed in place, for example once its URL is interpolated.
  • Relocation coordinates. Relocation groupId/artifactId/version are checked against the artifact-coordinate character set before a RelocatedArtifact is built; malformed components fail the descriptor read rather than entering resolution. A follow-up commit covers the remaining rejected character classes.
  • Metadata version tokens. Version and snapshot-timestamp tokens read from maven-metadata.xml are validated before being spliced into a resolved version, so malformed metadata fails the read rather than producing a malformed coordinate. The rejection message names the field.

Each change is a separate commit.


Draft while related code paths are reviewed — the same validation may be needed in sibling implementations of these interfaces, and I would rather establish that before asking for review time.

A systemPath change was removed from this PR: it broke MavenITmng4379TransitiveSystemPathInterpolatedWithEnvVarTest, which covers deliberate MNG-4379 behaviour — a dependency resolved from a repository declaring its own system-scope dependency with the path interpolated from an environment variable.

@slachiewicz
slachiewicz force-pushed the pr/artifact-resolution-3.9.x branch from 9f8d489 to 2b4441a Compare August 30, 2026 18:32
@slachiewicz slachiewicz added this to the 3.9.17 milestone Aug 30, 2026
@slachiewicz
slachiewicz marked this pull request as draft August 30, 2026 18:54
Repositories declared by a resolved model no longer replace a same-id repository
supplied by the request or session; the ids supplied at resolver construction keep
their precedence on the replace pass. A repository the model itself declared is
still refreshed in place, e.g. once its URL has been interpolated.
Repositories declared by a resolved model no longer replace a same-id repository
supplied by the request or session; the ids supplied at resolver construction keep
their precedence on the replace pass. A repository the model itself declared is
still refreshed in place, e.g. once its URL has been interpolated.
…data

DefaultMetadataReader now checks parsed metadata the same way
DefaultVersionResolver already does: version tokens (release, latest,
versions, snapshot versions, snapshot timestamp) and plugin entries'
artifactId and prefix must be valid coordinate components, rejecting
"..", '/', '\\', ':' and ISO control characters. Callers that read
metadata through this class already treat a read failure as invalid
metadata, so a rejected document degrades gracefully instead of being
adopted as a resolved version or plugin artifactId.
… ones"

This reverts commit ef74d16.

ProjectModelResolver tracks in repositoryIds only the ids a model has declared,
so the replace path is reached only for an id this model registered earlier.
Guarding it on the id also being present in the externally supplied list
therefore never protected an externally supplied repository; it only blocked a
model from refreshing its own declaration when the two ids happened to match.
MavenITmng5639ImportScopePomResolutionTest does exactly that: it declares
central in the POM and relies on the refreshed URL once interpolation has run.

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

Well-adapted 3.9.x backport of the coordinate validation and repository precedence hardening. This completes the 4-PR series (#12949 master, #12944 4.0.x, #12952 3.10.x, #12955 3.9.x).

Highlights:

  • The ProjectModelResolver revert is correct: in 3.9.x, ProjectModelResolver only puts model-declared ids in repositoryIds, so the external-id guard would never protect an external repo — it would instead break MavenITmng5639ImportScopePomResolutionTest. Good catch.
  • The validation logic is consistent with the other 3 variants, properly adapted for the 3.9.x codebase.
  • CI passes on all platforms.

Minor observations (non-blocking, already filed on master #12949):

  • Control characters in rejected values are embedded verbatim in error messages (minor log injection risk).
  • Silent return when a model-declared repository conflicts with an external id — a debug log would aid troubleshooting.
  • Validation logic duplication is acceptable for a stabilized branch.
  • The 3.10.x variant adds validation in DefaultRepositoryMetadataManager.readMetadata() that this variant doesn't cover — low risk since the compat path is primarily used during deployment.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

@slachiewicz

Copy link
Copy Markdown
Member Author

Related work in maven-resolver, for reviewer awareness: apache/maven-resolver#2092 backports the coordinate component checking to the maven-resolver-1.9.x line, including PathUtils, which does not exist there today.

That matters for this branch specifically: 3.9.x pins resolver 1.9.27, so it is #2092 rather than the master-line PRs that would eventually reach it. Until that pin moves, the check in this PR is the only one on the path.

Worth a reviewer decision on whether the check should stay here once a resolver bump lands.

This comment was created with AI assistance.

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.

2 participants