diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/util/NamingUtilities.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/util/NamingUtilities.java index 73a26638d7..4f88dc477d 100644 --- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/util/NamingUtilities.java +++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/util/NamingUtilities.java @@ -37,7 +37,7 @@ public final class NamingUtilities { public final static Set VALID_NAME_CHARSET = Collections.unmodifiableSet( - Set.of('.', '-', '=', '@', ' ', '_', '(', ')', '[', ']', '~')); + Set.of('.', '-', '=', '@', ' ', '_', '(', ')', '[', ']', '~', '+')); private NamingUtilities() { } diff --git a/Ghidra/Framework/Project/src/test/java/ghidra/framework/model/ProjectLocatorTest.java b/Ghidra/Framework/Project/src/test/java/ghidra/framework/model/ProjectLocatorTest.java index 92c9df0fc6..17599855b3 100644 --- a/Ghidra/Framework/Project/src/test/java/ghidra/framework/model/ProjectLocatorTest.java +++ b/Ghidra/Framework/Project/src/test/java/ghidra/framework/model/ProjectLocatorTest.java @@ -28,6 +28,7 @@ import ghidra.framework.Application; import ghidra.framework.OperatingSystem; import ghidra.framework.protocol.ghidra.GhidraURL; import ghidra.framework.protocol.ghidra.Handler; +import ghidra.util.NamingUtilities; public class ProjectLocatorTest extends AbstractGenericTest { @@ -41,7 +42,7 @@ public class ProjectLocatorTest extends AbstractGenericTest { // private URL toGhidraLocalURL(String path) throws MalformedURLException, URISyntaxException { - return new URI(GhidraURL.PROTOCOL, path, null).toURL(); + return new URI(GhidraURL.PROTOCOL, null, path, null).toURL(); } @Test @@ -158,6 +159,48 @@ public class ProjectLocatorTest extends AbstractGenericTest { } } + @Test + public void testSpecialCharsInPath() throws Exception { + + StringBuilder specialChars = new StringBuilder(); + for (Character c : NamingUtilities.VALID_NAME_CHARSET) { + specialChars.append(c); + } + + String dirName = "bill" + specialChars; + String projName = "bob" + specialChars; + + ProjectLocator pl = new ProjectLocator("c:\\" + dirName, projName); + assertEquals(toGhidraLocalURL("/c:/" + dirName + "/" + projName), pl.getURL()); + assertEquals("/c:/" + dirName + "/", pl.getLocation()); + assertEquals(new File("/c:/" + dirName + "/" + projName + ".rep"), pl.getProjectDir()); + assertEquals(new File("/c:/" + dirName + "/" + projName + ".gpr"), pl.getMarkerFile()); + assertEquals(projName, pl.getName()); + assertTrue(pl.isWindowsOnlyLocation()); + + if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) { + assertEquals("c:\\" + dirName + "\\" + projName + ".rep", + pl.getProjectDir().getAbsolutePath()); + assertEquals("c:\\" + dirName + "\\" + projName + ".gpr", + pl.getMarkerFile().getAbsolutePath()); + } + + pl = new ProjectLocator("/c:/" + dirName, projName); + assertEquals(toGhidraLocalURL("/c:/" + dirName + "/" + projName), pl.getURL()); + assertEquals("/c:/" + dirName + "/", pl.getLocation()); + assertEquals(new File("/c:/" + dirName + "/" + projName + ".rep"), pl.getProjectDir()); + assertEquals(new File("/c:/" + dirName + "/" + projName + ".gpr"), pl.getMarkerFile()); + assertEquals(projName, pl.getName()); + assertTrue(pl.isWindowsOnlyLocation()); + + if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) { + assertEquals("c:\\" + dirName + "\\" + projName + ".rep", + pl.getProjectDir().getAbsolutePath()); + assertEquals("c:\\" + dirName + "\\" + projName + ".gpr", + pl.getMarkerFile().getAbsolutePath()); + } + } + @Test public void testTempPath() throws Exception { diff --git a/Ghidra/Framework/Project/src/test/java/ghidra/framework/protocol/ghidra/GhidraURLTest.java b/Ghidra/Framework/Project/src/test/java/ghidra/framework/protocol/ghidra/GhidraURLTest.java index c2833b7537..fdc3094418 100644 --- a/Ghidra/Framework/Project/src/test/java/ghidra/framework/protocol/ghidra/GhidraURLTest.java +++ b/Ghidra/Framework/Project/src/test/java/ghidra/framework/protocol/ghidra/GhidraURLTest.java @@ -27,6 +27,7 @@ import generic.test.AbstractGenericTest; import ghidra.framework.client.*; import ghidra.framework.model.ProjectLocator; import ghidra.framework.protocol.ghidra.GhidraURLConnection.StatusCode; +import ghidra.util.NamingUtilities; public class GhidraURLTest extends AbstractGenericTest { @@ -110,6 +111,19 @@ public class GhidraURLTest extends AbstractGenericTest { assertEquals(url, ghidraUrl); assertEquals(loc, GhidraURL.getProjectStorageLocator(ghidraUrl)); + StringBuilder specialChars = new StringBuilder(); + for (Character c : NamingUtilities.VALID_NAME_CHARSET) { + specialChars.append(c); + } + + loc = new ProjectLocator("/a/b" + specialChars, "Test" + specialChars); + assertEquals("/a/b" + specialChars + "/", loc.getLocation()); + assertFalse(loc.isWindowsOnlyLocation()); + ghidraUrl = GhidraURL.makeURL(loc); + url = toGhidraLocalURL("/a/b" + specialChars + "/Test" + specialChars, null); + assertEquals(url, ghidraUrl); + assertEquals(loc, GhidraURL.getProjectStorageLocator(ghidraUrl)); + try { new ProjectLocator("a/b", "Test"); fail("relative path should not be permitted");