mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 15:57:12 +08: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.net.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -58,6 +60,9 @@ public class BSimServerInfo implements Comparable<BSimServerInfo> {
|
|||||||
|
|
||||||
private String shortDbName; // lazy: short DB Name
|
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
|
* Construct a new {@link BSimServerInfo} object
|
||||||
*
|
*
|
||||||
@@ -196,13 +201,7 @@ public class BSimServerInfo implements Comparable<BSimServerInfo> {
|
|||||||
}
|
}
|
||||||
path = urlDecode(checkURLField(path, "path"));
|
path = urlDecode(checkURLField(path, "path"));
|
||||||
if (dbType == DBType.file) {
|
if (dbType == DBType.file) {
|
||||||
if (path.endsWith("/")) {
|
path = cleanupFilename(path);
|
||||||
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 '/'
|
|
||||||
}
|
}
|
||||||
else if (path.contains("/")) {
|
else if (path.contains("/")) {
|
||||||
throw new IllegalArgumentException("Invalid dbName in URL: " + path);
|
throw new IllegalArgumentException("Invalid dbName in URL: " + path);
|
||||||
@@ -246,6 +245,12 @@ public class BSimServerInfo implements Comparable<BSimServerInfo> {
|
|||||||
|
|
||||||
private static String cleanupFilename(String name) {
|
private static String cleanupFilename(String name) {
|
||||||
// transform dbName into acceptable H2 DB file path
|
// 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();
|
String dbName = name.trim();
|
||||||
dbName = dbName.replace("\\", "/");
|
dbName = dbName.replace("\\", "/");
|
||||||
if ((!dbName.startsWith("/") && !isWindowsFilePath(dbName)) || dbName.endsWith("/")) {
|
if ((!dbName.startsWith("/") && !isWindowsFilePath(dbName)) || dbName.endsWith("/")) {
|
||||||
|
|||||||
+2
-2
@@ -246,7 +246,6 @@ public class BSimH2FileDBConnectionManager {
|
|||||||
// Remove leading '/' before drive letter
|
// Remove leading '/' before drive letter
|
||||||
dbName = dbName.substring(1);
|
dbName = dbName.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "jdbc:h2:" + dbName;
|
return "jdbc:h2:" + dbName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,6 +256,7 @@ public class BSimH2FileDBConnectionManager {
|
|||||||
|
|
||||||
// Set database URL
|
// Set database URL
|
||||||
// NOTE: keywords 'key' and 'value' are used by KeyValueTable as column names
|
// NOTE: keywords 'key' and 'value' are used by KeyValueTable as column names
|
||||||
|
|
||||||
bds.setUrl(getH2FileUrl() +
|
bds.setUrl(getH2FileUrl() +
|
||||||
";MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;NON_KEYWORDS=key,value");
|
";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.
|
* 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
|
* be created. The {@link #exists()} method should be used to check for the database
|
||||||
* existence prior to connecting the first time.
|
* existence prior to connecting the first time.
|
||||||
* @return database connection
|
* @return database connection
|
||||||
|
|||||||
+124
@@ -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