diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 2132e67ad4..8fc6c49e86 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -8,6 +8,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/2052[#2052]: Split issue statistics in 2 pie-charts * https://github.com/devonfw/IDEasy/issues/822[#822] : Added Cwd path limit in shell +* https://github.com/devonfw/IDEasy/issues/2088[#2088]: Skip malformed PATH entries instead of failing with InvalidPathException The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/46?closed=1[milestone 2026.07.001]. diff --git a/cli/src/main/java/com/devonfw/tools/ide/common/SystemPath.java b/cli/src/main/java/com/devonfw/tools/ide/common/SystemPath.java index 87ff6b0352..05ed203046 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/common/SystemPath.java +++ b/cli/src/main/java/com/devonfw/tools/ide/common/SystemPath.java @@ -3,6 +3,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.LinkOption; import java.nio.file.Path; import java.util.ArrayList; @@ -16,6 +17,9 @@ import java.util.regex.Pattern; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.os.SystemInfoImpl; import com.devonfw.tools.ide.os.WindowsPathSyntax; @@ -33,6 +37,8 @@ */ public class SystemPath { + private static final Logger LOG = LoggerFactory.getLogger(SystemPath.class); + private static final Pattern REGEX_WINDOWS_PATH = Pattern.compile("([a-zA-Z]:)?(\\\\[a-zA-Z0-9\\s_.-]+)+\\\\?"); private final char pathSeparator; @@ -96,7 +102,13 @@ public SystemPath(IdeContext context, String envPath, Path ideRoot, Path softwar this(context, pathSeparator, extraPathEntries, new HashMap<>(), new ArrayList<>()); String[] envPaths = envPath.split(Character.toString(pathSeparator)); for (String segment : envPaths) { - Path path = Path.of(segment); + Path path; + try { + path = Path.of(segment); + } catch (InvalidPathException e) { + LOG.warn("Ignoring invalid PATH entry '{}' - {}", segment, e.getMessage()); + continue; + } String tool = getTool(path, ideRoot); if (tool == null) { this.paths.add(path); diff --git a/cli/src/test/java/com/devonfw/tools/ide/common/SystemPathTest.java b/cli/src/test/java/com/devonfw/tools/ide/common/SystemPathTest.java index 3b7be3335a..1c05bf87a7 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/common/SystemPathTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/common/SystemPathTest.java @@ -12,6 +12,7 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeTestContext; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.os.SystemInfo; import com.devonfw.tools.ide.os.SystemInfoMock; @@ -142,6 +143,25 @@ void testFindBinaryFindsNothingWithoutFilter() { assertThat(result).isEqualTo(test); } + @Test + void testConstructorSkipsMalformedPathEntryAndKeepsValidOnes() { + // arrange + IdeTestContext context = newContext("find-binary", "project/workspaces", false); + String validEntryBefore = "C:\\Tools\\bin"; + // (char) 0 is an illegal NUL character, making Path.of throw InvalidPathException on every OS + String malformedEntry = "broken" + (char) 0 + "entry"; + String validEntryAfter = "C:\\Other\\bin"; + String envPath = validEntryBefore + ';' + malformedEntry + ';' + validEntryAfter; + + // act + SystemPath systemPath = new SystemPath(context, envPath, context.getIdeRoot(), context.getSoftwarePath(), ';', new ArrayList<>()); + + // assert + String result = systemPath.toString(); + assertThat(result).contains(validEntryBefore).contains(validEntryAfter); + assertThat(context).log(IdeLogLevel.WARNING).hasMessageContaining("Ignoring invalid PATH entry"); + } + private static boolean checkPathToIgnoreLowercase(Path p, String toIgnore) { String s = p.toAbsolutePath().toString().replace('\\', '/').toLowerCase(Locale.ROOT); return !s.contains(toIgnore);