This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch fix/defensive-null-checks-and-resource-leak
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git

commit fe19c43c99ad8b033d0299716fec87817a083bcd
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Jun 30 22:48:45 2026 +0000

    Fix potential NPEs in IpcClient and resource leak in DependencyGraphParser
    
    - IpcClient.getJarPath(): handle null ClassLoader (bootstrap classes)
      and null resource lookup with explicit null checks
    - IpcClient.receive(): capture volatile `input` field in local variable
      before use to prevent NPE from concurrent close()
    - IpcClient.getAddress(): capture volatile `socket` field in local
      variable and add null check to prevent NPE during concurrent close()
    - DependencyGraphParser.parseMultiResource(): wrap BufferedReader in
      try-with-resources to prevent stream leak on exception
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../org/eclipse/aether/named/ipc/IpcClient.java    | 27 ++++++++++++++++++----
 .../internal/test/util/DependencyGraphParser.java  | 15 ++++++------
 2 files changed, 30 insertions(+), 12 deletions(-)

diff --git 
a/maven-resolver-named-locks-ipc/src/main/java/org/eclipse/aether/named/ipc/IpcClient.java
 
b/maven-resolver-named-locks-ipc/src/main/java/org/eclipse/aether/named/ipc/IpcClient.java
index 852bdcc66..751d872d1 100644
--- 
a/maven-resolver-named-locks-ipc/src/main/java/org/eclipse/aether/named/ipc/IpcClient.java
+++ 
b/maven-resolver-named-locks-ipc/src/main/java/org/eclipse/aether/named/ipc/IpcClient.java
@@ -29,6 +29,7 @@ import java.io.InterruptedIOException;
 import java.io.PrintWriter;
 import java.io.RandomAccessFile;
 import java.net.SocketAddress;
+import java.net.URL;
 import java.nio.channels.ByteChannel;
 import java.nio.channels.Channels;
 import java.nio.channels.FileLock;
@@ -262,7 +263,15 @@ public class IpcClient {
     private String getJarPath(Class<?> clazz) {
         String classpath;
         String className = clazz.getName().replace('.', '/') + ".class";
-        String url = clazz.getClassLoader().getResource(className).toString();
+        ClassLoader classLoader = clazz.getClassLoader();
+        if (classLoader == null) {
+            classLoader = ClassLoader.getSystemClassLoader();
+        }
+        URL resource = classLoader.getResource(className);
+        if (resource == null) {
+            throw new IllegalStateException("Unable to find resource for class 
" + clazz.getName());
+        }
+        String url = resource.toString();
         if (url.startsWith("jar:")) {
             url = url.substring("jar:".length(), url.indexOf("!/"));
             if (url.startsWith("file:")) {
@@ -288,11 +297,15 @@ public class IpcClient {
     void receive() {
         try {
             while (true) {
-                int id = input.readInt();
-                int sz = input.readInt();
+                DataInputStream in = input;
+                if (in == null) {
+                    throw new IOException("Connection closed");
+                }
+                int id = in.readInt();
+                int sz = in.readInt();
                 List<String> s = new ArrayList<>(sz);
                 for (int i = 0; i < sz; i++) {
-                    s.add(input.readUTF());
+                    s.add(in.readUTF());
                 }
                 CompletableFuture<List<String>> f = responses.remove(id);
                 if (f == null) {
@@ -445,8 +458,12 @@ public class IpcClient {
     }
 
     private String getAddress() {
+        SocketChannel s = socket;
+        if (s == null) {
+            return "[closed]";
+        }
         try {
-            return SocketFamily.toString(socket.getLocalAddress());
+            return SocketFamily.toString(s.getLocalAddress());
         } catch (IOException e) {
             return "[not bound]";
         }
diff --git 
a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
 
b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
index 18da45bb7..b4c060fb2 100644
--- 
a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
+++ 
b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
@@ -158,14 +158,15 @@ public class DependencyGraphParser {
             throw new IOException("Could not find classpath resource " + 
prefix + resource);
         }
 
-        BufferedReader reader = new BufferedReader(new 
InputStreamReader(res.openStream(), StandardCharsets.UTF_8));
-
-        List<DependencyNode> ret = new ArrayList<>();
-        DependencyNode root = null;
-        while ((root = parse(reader)) != null) {
-            ret.add(root);
+        try (BufferedReader reader =
+                new BufferedReader(new InputStreamReader(res.openStream(), 
StandardCharsets.UTF_8))) {
+            List<DependencyNode> ret = new ArrayList<>();
+            DependencyNode root = null;
+            while ((root = parse(reader)) != null) {
+                ret.add(root);
+            }
+            return ret;
         }
-        return ret;
     }
 
     /**

Reply via email to