GP-6706 h2 database name checks

This commit is contained in:
James
2026-04-15 16:21:37 -04:00
parent 5f211c313f
commit 9cf1eef96d
3 changed files with 138 additions and 9 deletions

View File

@@ -19,6 +19,8 @@ import java.io.Closeable;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.StringUtils;
@@ -58,6 +60,9 @@ public class BSimServerInfo implements Comparable<BSimServerInfo> {
private String shortDbName; // lazy: short DB Name
private static String BAD_H2_CHARS = "';\"";
private static Pattern BAD_H2_CHARS_PATTERN = Pattern.compile(".*[" + BAD_H2_CHARS + "].*");
/**
* Construct a new {@link BSimServerInfo} object
*
@@ -196,13 +201,7 @@ public class BSimServerInfo implements Comparable<BSimServerInfo> {
}
path = urlDecode(checkURLField(path, "path"));
if (dbType == DBType.file) {
if (path.endsWith("/")) {
throw new IllegalArgumentException("Missing DB filepath in URL: " + url);
}
if (!path.endsWith(H2_FILE_EXTENSION)) {
path += H2_FILE_EXTENSION;
}
// TODO: handle Windows path with drive letter - need to remove leading '/'
path = cleanupFilename(path);
}
else if (path.contains("/")) {
throw new IllegalArgumentException("Invalid dbName in URL: " + path);
@@ -246,6 +245,12 @@ public class BSimServerInfo implements Comparable<BSimServerInfo> {
private static String cleanupFilename(String name) {
// transform dbName into acceptable H2 DB file path
Matcher m = BAD_H2_CHARS_PATTERN.matcher(name);
if (m.matches()) {
throw new IllegalArgumentException("Bad character in H2 database path. " +
"Disallowed characters: " + BAD_H2_CHARS);
}
String dbName = name.trim();
dbName = dbName.replace("\\", "/");
if ((!dbName.startsWith("/") && !isWindowsFilePath(dbName)) || dbName.endsWith("/")) {

View File

@@ -246,7 +246,6 @@ public class BSimH2FileDBConnectionManager {
// Remove leading '/' before drive letter
dbName = dbName.substring(1);
}
return "jdbc:h2:" + dbName;
}
@@ -257,6 +256,7 @@ public class BSimH2FileDBConnectionManager {
// Set database URL
// NOTE: keywords 'key' and 'value' are used by KeyValueTable as column names
bds.setUrl(getH2FileUrl() +
";MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;NON_KEYWORDS=key,value");
@@ -276,7 +276,7 @@ public class BSimH2FileDBConnectionManager {
/**
* Get a connection to the H2 file database.
* It is important to note that if the database does not exist and empty one will
* It is important to note that if the database does not exist an empty one will
* be created. The {@link #exists()} method should be used to check for the database
* existence prior to connecting the first time.
* @return database connection

View File

@@ -0,0 +1,124 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.features.bsim.query.client;
import static org.junit.Assert.*;
import java.net.URI;
import java.net.URL;
import org.junit.Test;
import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.BSimServerInfo.DBType;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
public class BSimServerInfoTest extends AbstractGhidraHeadlessIntegrationTest {
@Test
public void testBadFilename1() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo("C:\\dir\\test\"test");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("characters"));
}
@Test
public void testBadFilename2() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo(DBType.file, "user", 1, "/test'test");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("characters"));
}
@Test
public void testBadFilename3() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
URL url = new URI("file:/test;test").toURL();
BSimServerInfo h2Info = new BSimServerInfo(url);
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("characters"));
}
@Test
public void testBadDirectory1() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo("C:\\dir;1\\test");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("characters"));
}
@Test
public void testBadDirectory2() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo("C:\\dir'1\\test");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("characters"));
}
@Test
public void testBadDirectory3() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo("/dir1/dir\"/2/testdb");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("characters"));
}
@Test
public void testBadPathWindows() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo("C:\\directory\\");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("Invalid absolute file path"));
}
@Test
public void testBadPathLinux() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo("/dir1/dir2/");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("Invalid absolute file path"));
}
@Test
public void testBadPathLinux2() {
Exception e = assertThrows(IllegalArgumentException.class, () -> {
BSimServerInfo h2Info = new BSimServerInfo("dir1/dir2/dir3/file");
assertNull(h2Info);
});
assertTrue(e.getMessage().contains("Invalid absolute file path"));
}
@Test
public void testPaths() {
BSimServerInfo h2Info = new BSimServerInfo("/dir1/dir2/dir3/file");
assertEquals("/dir1/dir2/dir3/file.mv.db", h2Info.getDBName());
h2Info = new BSimServerInfo("/dir1/dir2/dir3/file.mv.db");
assertEquals("/dir1/dir2/dir3/file.mv.db", h2Info.getDBName());
h2Info = new BSimServerInfo("C:\\dir1 2\\file3 4");
assertEquals("C:/dir1 2/file3 4.mv.db", h2Info.getDBName());
}
}