mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-04-25 17:25:17 +02:00
GP-6706 h2 database name checks
This commit is contained in:
@@ -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("/")) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user