Copilot commented on code in PR #2135:
URL: https://github.com/apache/maven-resolver/pull/2135#discussion_r3993266654


##########
maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java:
##########
@@ -159,25 +140,17 @@ public LocalRepositoryManager 
newInstance(RepositorySystemSession session, Local
                 || trackingFilename.contains("..")) {
             trackingFilename = DEFAULT_TRACKING_FILENAME;
         }
-        boolean legacyTrackingFallback =
-                ConfigUtils.getBoolean(session, 
DEFAULT_LEGACY_TRACKING_FALLBACK, CONFIG_PROP_LEGACY_TRACKING_FALLBACK);
+        boolean legacyLocalRepository =
+                ConfigUtils.getBoolean(session, 
DEFAULT_LEGACY_LOCAL_REPOSITORY, CONFIG_PROP_LEGACY_LOCAL_REPOSITORY);

Review Comment:
   The old `CONFIG_PROP_LEGACY_TRACKING_FALLBACK` setting is no longer read 
here. A user who explicitly set that opt-out to `false` will silently get the 
new `legacyLocalRepository` default of `true`, enabling the 
same-ID/different-URL acceptance path and weakening the provenance protection 
they selected. Preserve the old property as a compatibility alias (and retain 
its public constant) when resolving the new option.



##########
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/remoterepo/RepositoryKeyFunctionFactory.java:
##########
@@ -50,7 +75,29 @@ public interface RepositoryKeyFunctionFactory {
      *                         no configuration lookup happens but the {@code 
defaultValue} is used to create the
      *                         repository key function.
      * @return The repository key function.
+     * @deprecated Use {@link #repositoryKeyFunction(Class, 
RepositorySystemSession, String, String...)} instead.
+     */
+    @Deprecated
+    default RepositoryKeyFunction repositoryKeyFunction(
+            Class<?> owner, RepositorySystemSession session, String 
defaultValue, String configurationKey) {
+        return repositoryKeyFunction(owner, session, defaultValue, new 
String[] {configurationKey});
+    }
+
+    /**
+     * Method that based on configuration returns the "repository key 
function". The returned function will be session
+     * cached if session is equipped with cache, otherwise it will be non 
cached. Method never returns {@code null}.
+     * Only the {@code configurationKey} parameter may be {@code null} in 
which case no configuration lookup happens
+     * but the {@code defaultValue} is directly used instead.
+     *
+     * @param owner The "owner" of key function (used to create cache-key), 
must not be {@code null}.
+     * @param session The repository session, must not be {@code null}.
+     * @param defaultValue The default value of repository key configuration, 
must not be {@code null}.
+     * @param configurationKeys The configuration keys to lookup configuration 
from, may be {@code null}, in which case
+     *                         no configuration lookup happens but the {@code 
defaultValue} is used to create the
+     *                         repository key function.
+     * @return The repository key function.
+     * @since 2.0.23
      */
     RepositoryKeyFunction repositoryKeyFunction(
-            Class<?> owner, RepositorySystemSession session, String 
defaultValue, String configurationKey);
+            Class<?> owner, RepositorySystemSession session, String 
defaultValue, String... configurationKeys);

Review Comment:
   Adding the varargs overload as the new abstract method is not source- or 
binary-compatible with existing `RepositoryKeyFunctionFactory` implementations 
that implement only the former `String configurationKey` method. The deprecated 
method being a default does not make those implementations implement the new 
abstract signature; calls through the new tracking/system defaults can fail to 
link. Keep a compatible abstract contract and make the varargs form an adapting 
default, or otherwise provide both implementations.



##########
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/remoterepo/RepositoryKeyFunctionFactory.java:
##########
@@ -32,10 +33,34 @@ public interface RepositoryKeyFunctionFactory {
      *
      * @param session The repository session, must not be {@code null}.
      * @return The repository key function.
-     * @see #repositoryKeyFunction(Class, RepositorySystemSession, String, 
String)
+     * @see #repositoryKeyFunction(Class, RepositorySystemSession, String, 
String[])
      * @see 
org.eclipse.aether.ConfigurationProperties#REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION
      */
-    RepositoryKeyFunction systemRepositoryKeyFunction(RepositorySystemSession 
session);
+    default RepositoryKeyFunction 
systemRepositoryKeyFunction(RepositorySystemSession session) {
+        return repositoryKeyFunction(
+                RepositoryKeyFunctionFactory.class,
+                session,
+                
ConfigurationProperties.DEFAULT_REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION,
+                
ConfigurationProperties.REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION);
+    }
+
+    /**
+     * Returns system-wide tracking repository key function.
+     *
+     * @param session The repository session, must not be {@code null}.
+     * @return The repository key function.
+     * @see #repositoryKeyFunction(Class, RepositorySystemSession, String, 
String[])
+     * @see 
org.eclipse.aether.ConfigurationProperties#REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION
+     * @since 2.0.23
+     */
+    default RepositoryKeyFunction 
trackingRepositoryKeyFunction(RepositorySystemSession session) {
+        return repositoryKeyFunction(
+                RepositoryKeyFunctionFactory.class,
+                session,
+                
ConfigurationProperties.DEFAULT_REPOSITORY_TRACKING_REPOSITORY_KEY_FUNCTION,
+                
ConfigurationProperties.REPOSITORY_TRACKING_REPOSITORY_KEY_FUNCTION,
+                
ConfigurationProperties.REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION);

Review Comment:
   Both convenience methods pass `RepositoryKeyFunctionFactory.class` as the 
cache owner, while `DefaultRepositoryKeyFunctionFactory` uses that owner as the 
session-cache namespace. As soon as one function is requested for a 
repository/context, the other can read the cached value and return the wrong 
key (for example, `nid` is reused as the default `nid_hurl` tracking key), 
making behavior depend on call order. Use distinct cache namespaces or include 
the selected configuration in the cache key.



##########
maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java:
##########
@@ -620,6 +620,32 @@ public enum HttpVersion {
 
     public static final String 
DEFAULT_REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION = "nid";
 
+    /**
+     * Repository key function used for the provenance tracking entries this 
local repository manager writes and
+     * consults, and for nothing else. With an ID-only key, "came from
+     * repository X" means X's possibly colliding label: a repository declared 
in an untrusted (for example,
+     * transitively resolved) POM under the same ID as a trusted repository 
would be tracked as the same origin and
+     * could poison a shared local repository. The default is therefore the 
URL-qualified {@code "nid_hurl"}
+     * function, scoped to tracking entries only: repository identity 
everywhere else (repository aggregation and
+     * mirror merging, artifact and metadata path composition, split local 
repository prefixes) keeps following the
+     * system-wide key function, whose default is unchanged - so no 
aggregation semantics change and no local
+     * repository re-layout occurs. If the system-wide function

Review Comment:
   This description still says artifact/metadata path composition and split 
local-repository prefixes use the system-wide key and that no local re-layout 
occurs, but `DefaultLocalPathPrefixComposerFactory` now passes 
`trackingRepositoryKeyFunction`. With the default `nid_hurl` tracking key, 
split paths can include the URL hash. Update this public configuration 
documentation to describe the tracking-key-based path behavior.



##########
maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java:
##########
@@ -107,22 +81,29 @@ public class EnhancedLocalRepositoryManagerFactory 
implements LocalRepositoryMan
     public static final boolean DEFAULT_VERIFY_REAL_PATH = true;
 
     /**
-     * Whether to enable "legacy tracking fallback" in LRM. If starting 
"greenfield" with Resolver 2 enabled Maven,
-     * this should be {@code false}, but for smoother transition of users 
using Maven 3.9 or older versions, the default
-     * is {@code true}. When the local repository is shared across "older" and 
"newer" Maven versions (where "older"
-     * Maven versions are Resolver 1.x and "never" Maven versions are Resolver 
2.x based), the preferred way is to
-     * enable this feature. On the other hand, if local repository is 
exclusively used by "newer" Maven versions,
-     * like 3.10 or above, for improved Repository cache poisoning protection, 
this configuration is recommended
-     * to be set to {@code false}.
+     * Marks is local repository meant to be shared (or was shared) with 
legacy Maven 3.9 or older versions.
+     * Maven 3.9 and older versions suffer from "impostor" problem, where 
artifact and metadata origin was tracked
+     * only by the remote repository ID, where two remote repositories may 
share same ID but different URLs, in fact
+     * they may be completely unrelated to each other (ID clash by mistake), 
or, it may be due some sort of "impostor"
+     * attempt, where a malicious repository may pretend like some other 
repository.
+     * Right now, we intentionally default to {@code true} to ease users 
transitioning, and Resolver 2 will retain
+     * this "old" behavior (will observe legacy tracking entries and will 
store remote metadata as before). But,
+     * at some point in the future, the default value will be flipped to 
{@code true} (and same change is warmly
+     * recommended for modern Maven users, who do not intend to share local 
repository with older Maven versions.

Review Comment:
   The migration note says the default will eventually be flipped to `true`, 
but this option is already declared with a default of `true` on the next line 
and the surrounding text recommends `false` for modern-only repositories. The 
future value should be `false` so the documentation describes the intended 
security transition.



##########
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/remoterepo/RepositoryKeyFunctionFactory.java:
##########
@@ -32,10 +33,34 @@ public interface RepositoryKeyFunctionFactory {
      *
      * @param session The repository session, must not be {@code null}.
      * @return The repository key function.
-     * @see #repositoryKeyFunction(Class, RepositorySystemSession, String, 
String)
+     * @see #repositoryKeyFunction(Class, RepositorySystemSession, String, 
String[])
      * @see 
org.eclipse.aether.ConfigurationProperties#REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION
      */
-    RepositoryKeyFunction systemRepositoryKeyFunction(RepositorySystemSession 
session);
+    default RepositoryKeyFunction 
systemRepositoryKeyFunction(RepositorySystemSession session) {
+        return repositoryKeyFunction(
+                RepositoryKeyFunctionFactory.class,
+                session,
+                
ConfigurationProperties.DEFAULT_REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION,
+                
ConfigurationProperties.REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION);
+    }
+
+    /**
+     * Returns system-wide tracking repository key function.
+     *
+     * @param session The repository session, must not be {@code null}.
+     * @return The repository key function.
+     * @see #repositoryKeyFunction(Class, RepositorySystemSession, String, 
String[])
+     * @see 
org.eclipse.aether.ConfigurationProperties#REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION

Review Comment:
   The tracking-specific convenience method links to 
`REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION`, so generated API documentation 
points users at the wrong configuration property. This reference should name 
`REPOSITORY_TRACKING_REPOSITORY_KEY_FUNCTION` while noting the system property 
is only the fallback.



##########
maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManager.java:
##########
@@ -326,6 +332,27 @@ private boolean applyTracking(Path path, 
LocalArtifactResult result, Properties
                     result.setRepository(repository);
                     return true;
                 }
+                // Same-ID-different-URL fallback: if the tracking file 
contains a URL-qualified entry for the
+                // same repository ID but with a different URL hash (e.g. real 
Central tracked as
+                // "central-<sha1(realUrl)>=" but the current build overrides 
central to "file:target/null"),
+                // the exact lookup misses because sha1(realUrl) != 
sha1(file:target/null). Match by repo-ID
+                // prefix: any entry starting with "filename>repoId-" is 
accepted as originating from the same
+                // logical repository.
+                String repoIdPrefix = getKey(path, legacyKey + "-");
+                for (Object key : props.keySet()) {
+                    String k = key.toString();
+                    if (k.startsWith(repoIdPrefix) && !k.equals(getKey(path, 
trackingKey))) {

Review Comment:
   The same-ID fallback builds its prefix from `simpleRepositoryKeyFunction`, 
but that function is not just the repository ID for repository managers: it 
appends a mirror/context hash. A URL-qualified entry is keyed as `id-<url 
hash>` and therefore will not start with `id-<simple-key hash>-`, so the 
fallback added here fails for repository-manager repositories even when their 
IDs match. Derive the prefix from an ID-only key instead of the full simple key.



##########
maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/checksum/SummaryFileTrustedChecksumsSource.java:
##########
@@ -188,7 +184,8 @@ protected Map<String, String> doGetTrustedMetadataChecksums(
             List<ChecksumAlgorithmFactory> checksumAlgorithmFactories) {
         return doGetTrustedPathChecksums(
                 session,
-                localPathComposer.getPathForMetadata(metadata, 
repositoryKey(session, artifactRepository)),
+                localPathComposer.getPathForMetadata(
+                        metadata, repositoryKey(session, 
artifactRepository).get(0)),
                 artifactRepository,
                 checksumAlgorithmFactories);

Review Comment:
   This metadata path is always composed with the tracking key, even though the 
loop below intentionally checks both tracking and system repository keys. 
Existing summary files written with the previous default (`nid`) store metadata 
under the system-key path, so loading the fallback summary file still cannot 
find those entries. The lookup needs to try the corresponding metadata path for 
each repository key, not just the first one.
   
   This issue also appears on line 213 of the same file.



##########
maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceSupport.java:
##########
@@ -111,18 +102,22 @@ protected RemoteRepository normalizeRemoteRepository(
     }
 
     /**
-     * Returns repository key to be used on file system layout.
+     * Returns repository keys to be used on file system layout for user 
provided files. They are ordered as
+     * "most specific" (using {@link {@link 
RepositoryKeyFunctionFactory#trackingRepositoryKeyFunction(RepositorySystemSession)}}

Review Comment:
   This Javadoc contains a nested `{@link}` tag (`{@link {@link ...}}`), which 
is malformed and can produce invalid generated API documentation. Remove the 
inner tag and close the surrounding sentence after the single link.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to