Skip to content

Output, transport and consumer POM robustness fixes - #12951

Open
slachiewicz wants to merge 8 commits into
apache:masterfrom
slachiewicz:pr/cli-and-transport-master
Open

Output, transport and consumer POM robustness fixes#12951
slachiewicz wants to merge 8 commits into
apache:masterfrom
slachiewicz:pr/cli-and-transport-master

Conversation

@slachiewicz

@slachiewicz slachiewicz commented Aug 30, 2026

Copy link
Copy Markdown
Member

Robustness fixes across the CLI, transport and consumer POM.

  • Transfer listener output. Control characters in transfer messages are escaped so they render literally rather than being interpreted by the terminal. Tab and newline are preserved.
  • Transport base URI. Relative locations resolve against a slash-terminated base, so a relative reference cannot resolve outside it.
  • Mirror matching. isExternalRepo/isExternalHttpRepo parsed with java.net.URL, which throws on dav:, dav:http: and dav+http: — leaving those branches unreachable — and returned false on any parse failure, so an unparseable URL matched no external:* mirror. Parsing is now textual and an unparseable URL is treated as external.
  • Settings decryption messages. Decryption failure messages identify the server or profile property concerned rather than including the encrypted value.
  • Consumer POM repositories. The consumer POM now publishes only repositories the project's own POM declares; those present only via a parent POM or an active settings.xml profile are dropped, with a warning naming each. maven.consumer.pom.sanitizeRepositories=false restores the previous behaviour. This changes a published artifact format — see the note below.
  • mvnup resolution. mvnup reused hardcoded repositories and forced user.home, so a real settings.xml was never read. It now uses the settings the CLI already loaded and the configured local repository. Where the standalone resolver cannot honour the configuration — offline mode, a redirecting mirror, an active proxy — it is given no remote repositories and the affected strategies skip their remote work with a warning.

Release note for the consumer POM change: a downstream consumer relying on inheriting a repository declaration that existed only in a parent POM or the publisher's settings will need to declare that repository itself.

Each change is a separate commit.


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

@slachiewicz
slachiewicz marked this pull request as draft August 30, 2026 19:05
@slachiewicz
slachiewicz force-pushed the pr/cli-and-transport-master branch 2 times, most recently from 52ce9a5 to a118910 Compare August 30, 2026 22:01
@slachiewicz
slachiewicz marked this pull request as ready for review August 31, 2026 06:27

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

✅ Solid PR — Two Minor Style Observations

Well-structured multi-topic robustness PR with good test coverage across all changes: control character sanitization, fail-closed mirror matching, transport path traversal prevention, settings decryption message improvement, consumer POM repository restriction, and mvnup settings resolution. This is the master sibling of #12946 (maven-4.0.x), which was already approved.

Minor observations (non-blocking):

  1. Style (MavenITgh10210SettingsXmlDecryptTest.java:77): assertTrue(!log.contains(...))assertFalse(log.contains(...)) for readability and better assertion failure messages.

  2. Logging level (DefaultConsumerPomBuilder.java:603): The "publishing repository" message for retained repositories is logged at WARN. Unlike the dropped-repository message (which is genuinely a warning about a behavioral change), this message is purely informational — it confirms that a repository the project declared is being kept. Using WARN here will be noisy for projects declaring custom repositories, especially in CI pipelines that fail-on-warn. INFO or DEBUG would be more appropriate.

📋 PR Metadata

Aspect Current Suggested
Milestone (none) 4.1.0

🔀 Backport Status

  • maven-4.0.x#12946 (OPEN, reviewed & approved)

🤖 This review was generated by ForgeBot.

Repository-supplied strings (checksum mismatch messages, resource
names, repository ids/urls) were written straight to the console or
logger without any filtering of control characters. Add a small
sanitize() helper to AbstractMavenTransferListener (impl/maven-cli
and the deprecated compat/maven-embedder copy) that replaces C0
controls other than tab/newline, DEL, and C1 controls with visible
\uXXXX escapes, and apply it everywhere these listeners print
remote-derived text, so terminal output always reflects what was
actually printed.
Normalize the repository base URI to end with a slash before resolving a
relative get/put location, and centralize the containment check in a
shared helper. This keeps URI.resolve() on a whole path segment boundary
and makes get/put behave consistently regardless of whether the
configured repository URL carries a trailing slash.
isExternalRepo/isExternalHttpRepo parsed the repository URL with
java.net.URL, which has no stream handler for the dav/dav:http/dav+http
schemes wagon-webdav speaks and throws for any other unparseable URL;
both methods caught the exception and returned false, so such a
repository was classified as neither external nor external-http and
silently skipped the external:*/external:http:* mirror rules,
including the shipped external:http:* blocker. Parse the scheme and
host textually instead, the way the resolver's own mirror matcher
does, so these URLs are classified and matched like any other.
@slachiewicz
slachiewicz force-pushed the pr/cli-and-transport-master branch from 199708d to 30611a1 Compare August 31, 2026 14:35
The consumer POM's <repositories> section previously published every
effective-model repository except 'central', including repositories that
only reached the effective model through parent-POM inheritance or an
active settings.xml profile. Restrict publication to repository ids
declared in the project's own raw POM (model or profiles); everything
else is dropped, with a WARN naming each dropped repository and an INFO naming each retained
repository so operators can see what a deploy will publish.

The new user property maven.consumer.pom.sanitizeRepositories (default
true) restores the previous behavior when set to false.
The existing regression tests for consumer-POM repository scoping only
checked the intermediate Model object returned by transformNonPom().
Add a test that builds a bom-packaged project through the real public
PomBuilder entry point and serializes the result with the same
MavenStaxWriter the production ConsumerPomArtifactTransformer uses, so
the assertion is against the actual generated POM XML.
mvnup's compatibility and plugin-upgrade strategies built effective
models with a standalone session that always remapped user.home to a
test directory and hardcoded Maven Central plus an Apache snapshots
repository, ignoring the operator's real settings.xml (mirrors, proxies,
offline mode, blocked repositories) entirely.

ApiRunner.createSession() gains an isolateUserHome flag (existing
callers keep isolation; production callers can opt out). mvnup now
builds its session against the operator's real settings and local
repository when settings were loaded, drops the hardcoded snapshots
repository, and skips remote-model-dependent analysis with a warning
when the effective settings declare a mirror, proxy or offline mode the
standalone resolver cannot honor, instead of resolving around it.
isExternalRepo/isExternalHttpRepo in the legacy DefaultMirrorSelector parsed
the repository URL with java.net.URL, which has no stream handler for the
dav/dav:http/dav+http schemes wagon-webdav speaks and throws for any other
unparseable URL, silently skipping the external:*/external:http:* mirror
rules for such repositories. Parse the scheme and host textually instead,
matching the fix already applied to MavenRepositorySystem.
@slachiewicz
slachiewicz force-pushed the pr/cli-and-transport-master branch from 30611a1 to 225e9f1 Compare August 31, 2026 14:56
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