Skip to content

Commit 0322296

Browse files
tylfindevflow.devflow-routing-intake
andauthored
Fix Windows path parsing in JarScanner (#10664)
Fix Windows path parsing in JarScanner Use Paths.get(URI) instead of Paths.get(String) to correctly handle Windows drive letters in CodeSource locations (e.g. file:/C:/...). [DYNIS-50] Co-authored-by: devflow.devflow-routing-intake <devflow.devflow-routing-intake@kubernetes.us1.ddbuild.io>
1 parent a5a85e9 commit 0322296

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/symbol/JarScanner.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.datadog.debugger.symbol;
22

3+
import java.net.URI;
34
import java.net.URISyntaxException;
45
import java.net.URL;
56
import java.nio.file.Path;
@@ -65,6 +66,13 @@ public static String trimPrefixes(String classFilePath) {
6566
private static Path getPathFromPrefixedFileName(String locationStr, String prefix, int endIdx) {
6667
String fileName = locationStr.substring(prefix.length(), endIdx);
6768
LOGGER.debug("jar filename={}", fileName);
68-
return Paths.get(fileName);
69+
try {
70+
// Reconstruct a file URI and use Paths.get(URI) to correctly handle
71+
// platform-specific paths, including Windows drive letters (e.g. /C:/...)
72+
return Paths.get(new URI("file:" + fileName));
73+
} catch (URISyntaxException e) {
74+
LOGGER.debug("Failed to parse as URI: {}, falling back to direct path", fileName, e);
75+
return Paths.get(fileName);
76+
}
6977
}
7078
}

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/symbol/JarScannerTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
import java.net.URISyntaxException;
99
import java.net.URL;
1010
import java.net.URLClassLoader;
11+
import java.nio.file.Path;
1112
import java.security.CodeSource;
1213
import java.security.ProtectionDomain;
1314
import java.security.cert.Certificate;
1415
import org.junit.jupiter.api.Test;
16+
import org.junit.jupiter.api.condition.EnabledOnOs;
17+
import org.junit.jupiter.api.condition.OS;
1518

1619
class JarScannerTest {
1720
@Test
@@ -50,4 +53,28 @@ public void extractJarPathFromNestedJar() throws URISyntaxException {
5053
assertEquals(
5154
jarFileUrl.getFile(), JarScanner.extractJarPath(protectionDomain, null).toString());
5255
}
56+
57+
@Test
58+
@EnabledOnOs(OS.WINDOWS)
59+
public void extractJarPathFromFileOnWindows() throws URISyntaxException {
60+
URL mockLocation = mock(URL.class);
61+
when(mockLocation.toString()).thenReturn("file:/C:/apps/server/classes/");
62+
CodeSource codeSource = new CodeSource(mockLocation, (Certificate[]) null);
63+
ProtectionDomain protectionDomain = new ProtectionDomain(codeSource, null);
64+
Path result = JarScanner.extractJarPath(protectionDomain, SymDBReport.NO_OP);
65+
assertNotNull(result);
66+
assertTrue(result.toString().contains("server"));
67+
}
68+
69+
@Test
70+
@EnabledOnOs(OS.WINDOWS)
71+
public void extractJarPathFromJarOnWindows() throws URISyntaxException {
72+
URL mockLocation = mock(URL.class);
73+
when(mockLocation.toString()).thenReturn("jar:file:/C:/libs/app.jar!/com/example/");
74+
CodeSource codeSource = new CodeSource(mockLocation, (Certificate[]) null);
75+
ProtectionDomain protectionDomain = new ProtectionDomain(codeSource, null);
76+
Path result = JarScanner.extractJarPath(protectionDomain, SymDBReport.NO_OP);
77+
assertNotNull(result);
78+
assertTrue(result.toString().contains("app.jar"));
79+
}
5380
}

0 commit comments

Comments
 (0)