Skip to content

Infinite recursion risk in ToolchainDiscoverer.getCanonicalPath() for root paths #171

Description

@elharo

Summary

ToolchainDiscoverer.getCanonicalPath() has a recursive fallback that can cause infinite recursion or stack overflow for root paths where path.getParent() returns null.

Location

ToolchainDiscoverer.java:267-273

https://github.com/apache/maven-toolchains-plugin/blob/master/src/main/java/org/apache/maven/plugins/toolchain/jdk/ToolchainDiscoverer.java#L267-L273

Code

private static Path getCanonicalPath(Path path) {
    try {
        return path.toRealPath();
    } catch (IOException e) {
        return getCanonicalPath(path.getParent()).resolve(path.getFileName());
    }
}

Problem

  1. If path is a root directory (e.g. / on Linux or C:\ on Windows), path.getParent() returns null. The recursive call getCanonicalPath(null) throws NPE.
  2. If path.getParent() itself fails with IOException, this creates infinite recursion leading to stack overflow.
  3. The recursive approach also has no depth limit, so deeply nested paths that fail toRealPath() will recurse until stack overflow.

Impact

JDK discovery scanning directories like / or other root-relative paths could crash Maven with a stack overflow or NPE instead of gracefully skipping the problematic path.

Suggested Fix

Replace recursion with iteration:

private static Path getCanonicalPath(Path path) {
    try {
        return path.toRealPath();
    } catch (IOException e) {
        Path parent = path.getParent();
        if (parent == null) {
            return path;
        }
        return getCanonicalPath(parent).resolve(path.getFileName());
    }
}

Or better, use a non-recursive loop with null checks to eliminate the recursion entirely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions