Skip to content

Commit 787ac96

Browse files
committed
Merge remote-tracking branch 'origin/GP-1830_ghidra1_BSim_GSON'
2 parents 237d044 + 593fd98 commit 787ac96

18 files changed

+767
-1273
lines changed

Ghidra/Features/BSim/Module.manifest

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
##MODULE IP: Oxygen Icons - LGPL 3.0
22
MODULE FILE LICENSE: postgresql-15.3.tar.gz Postgresql License
33
MODULE FILE LICENSE: lib/postgresql-42.6.2.jar PostgresqlJDBC License
4-
MODULE FILE LICENSE: lib/json-simple-1.1.1.jar Apache License 2.0
54
MODULE FILE LICENSE: lib/commons-dbcp2-2.9.0.jar Apache License 2.0
65
MODULE FILE LICENSE: lib/commons-pool2-2.11.1.jar Apache License 2.0
76
MODULE FILE LICENSE: lib/commons-logging-1.2.jar Apache License 2.0

Ghidra/Features/BSim/build.gradle

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ dependencies {
3333
api project(":CodeCompare")
3434

3535
api "org.postgresql:postgresql:42.6.2"
36-
api "com.googlecode.json-simple:json-simple:1.1.1"
3736
api "org.apache.commons:commons-dbcp2:2.9.0"
3837
api "org.apache.commons:commons-pool2:2.11.1"
3938
api "commons-logging:commons-logging:1.2"

Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/gui/filters/ExecutableNameBSimFilterType.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,8 +17,6 @@
1717

1818
import java.sql.SQLException;
1919

20-
import org.json.simple.JSONObject;
21-
2220
import ghidra.features.bsim.query.client.IDSQLResolution;
2321
import ghidra.features.bsim.query.client.SQLEffects;
2422
import ghidra.features.bsim.query.description.ExecutableRecord;
@@ -38,7 +36,7 @@ public ExecutableNameBSimFilterType() {
3836

3937
@Override
4038
public void gatherSQLEffect(SQLEffects effect, FilterAtom atom, IDSQLResolution resolution)
41-
throws SQLException {
39+
throws SQLException {
4240
effect.setExeTable();
4341
StringBuilder buf = new StringBuilder();
4442
buf.append("exetable.name_exec = '").append(atom.value).append('\'');
@@ -47,10 +45,10 @@ public void gatherSQLEffect(SQLEffects effect, FilterAtom atom, IDSQLResolution
4745

4846
@Override
4947
public void gatherElasticEffect(ElasticEffects effect, FilterAtom atom,
50-
IDElasticResolution resolution) throws ElasticException {
48+
IDElasticResolution resolution) throws ElasticException {
5149
StringBuilder buffer = new StringBuilder();
5250
buffer.append("\"filter\": { \"term\": { \"name_exec\": \"");
53-
buffer.append(JSONObject.escape(atom.value));
51+
buffer.append(ElasticDatabase.escape(atom.value));
5452
buffer.append("\" } } ");
5553
effect.addStandalone(this, buffer.toString());
5654
}

Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/gui/filters/NotExecutableNameBSimFilterType.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,8 +17,6 @@
1717

1818
import java.sql.SQLException;
1919

20-
import org.json.simple.JSONObject;
21-
2220
import ghidra.features.bsim.query.client.IDSQLResolution;
2321
import ghidra.features.bsim.query.client.SQLEffects;
2422
import ghidra.features.bsim.query.description.ExecutableRecord;
@@ -37,7 +35,7 @@ public NotExecutableNameBSimFilterType() {
3735

3836
@Override
3937
public void gatherSQLEffect(SQLEffects effect, FilterAtom atom, IDSQLResolution resolution)
40-
throws SQLException {
38+
throws SQLException {
4139
effect.setExeTable();
4240
StringBuilder buf = new StringBuilder();
4341
buf.append("exetable.name_exec != '").append(atom.value).append('\'');
@@ -46,10 +44,10 @@ public void gatherSQLEffect(SQLEffects effect, FilterAtom atom, IDSQLResolution
4644

4745
@Override
4846
public void gatherElasticEffect(ElasticEffects effect, FilterAtom atom,
49-
IDElasticResolution resolution) throws ElasticException {
47+
IDElasticResolution resolution) throws ElasticException {
5048
StringBuilder buffer = new StringBuilder();
5149
buffer.append("\"must_not\": { \"term\": { \"name_exec\": \"");
52-
buffer.append(JSONObject.escape(atom.value));
50+
buffer.append(ElasticDatabase.escape(atom.value));
5351
buffer.append("\" } } ");
5452
effect.addStandalone(this, buffer.toString());
5553
}

Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/gui/filters/PathStartsBSimFilterType.java

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,7 +35,7 @@ public PathStartsBSimFilterType() {
3535

3636
@Override
3737
public void gatherSQLEffect(SQLEffects effect, FilterAtom atom, IDSQLResolution resolution)
38-
throws SQLException {
38+
throws SQLException {
3939
if (atom.value.length() > 0) {
4040
effect.setExeTable();
4141
effect.setPathTable();
@@ -47,11 +47,10 @@ public void gatherSQLEffect(SQLEffects effect, FilterAtom atom, IDSQLResolution
4747

4848
@Override
4949
public void gatherElasticEffect(ElasticEffects effect, FilterAtom atom,
50-
IDElasticResolution resolution) throws ElasticException {
51-
effect.addDocValue("String path = doc['path'].value; ");
50+
IDElasticResolution resolution) throws ElasticException {
51+
effect.addDocValue("String path = doc['path'].size() == 0 ? null : doc['path'].value; ");
5252
String argName = effect.assignArgument();
53-
effect.addScriptElement(this,
54-
"(path != null) && path.startsWith(params." + argName + ')');
53+
effect.addScriptElement(this, "(path != null) && path.startsWith(params." + argName + ')');
5554
effect.addParam(argName, atom.value);
5655
}
5756

Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimPostgresDBConnectionManager.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,9 @@ private Connection connect() throws SQLException, CancelledException {
284284

285285
String loginError = null;
286286

287-
serverInfo.setUserInfo(bds);
287+
if (bds.getPassword() == null) {
288+
serverInfo.setUserInfo(bds);
289+
}
288290

289291
connectionType = serverInfo.hasPassword() ? ConnectionType.SSL_Password_Authentication
290292
: ConnectionType.SSL_No_Authentication;

Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java

+37-4
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ protected void closing(Connection c) {
186186
* @throws SQLException if error occurs obtaining connection
187187
*/
188188
protected Connection initConnection() throws SQLException {
189-
if (db == null) {
189+
if (db == null || db.isClosed()) {
190190
db = ds.getConnection();
191191
}
192192
return db;
@@ -435,6 +435,12 @@ protected void createDatabase(Configuration config) throws SQLException {
435435
}
436436
}
437437

438+
/**
439+
* Drop this database
440+
* @throws SQLException if a database error occured
441+
*/
442+
abstract protected void dropDatabase() throws SQLException;
443+
438444
protected void setConnectionOnTables(Connection db) {
439445

440446
weightTable.setConnection(db);
@@ -1201,8 +1207,8 @@ public boolean initialize() {
12011207
}
12021208
else if (msg.contains("authentication failed") ||
12031209
msg.contains("requires a valid client certificate")) {
1204-
lasterror =
1205-
new BSimError(ErrorCategory.Authentication, "Could not authenticate with database");
1210+
lasterror = new BSimError(ErrorCategory.Authentication,
1211+
"Could not authenticate with database");
12061212
}
12071213
else if (msg.contains("does not exist") && !msg.contains(" role ")) {
12081214
lasterror = new BSimError(ErrorCategory.Nodatabase, cause.getMessage());
@@ -1572,6 +1578,9 @@ else if (query instanceof QueryExeInfo q) {
15721578
else if (query instanceof QueryExeCount q) {
15731579
fdbQueryExeCount(q);
15741580
}
1581+
else if (query instanceof DropDatabase q) {
1582+
fdbDatabaseDrop(q);
1583+
}
15751584
else if (query instanceof CreateDatabase q) {
15761585
fdbDatabaseCreate(q);
15771586
}
@@ -1622,7 +1631,8 @@ public QueryResponseRecord query(BSimQuery<?> query) {
16221631

16231632
lasterror = null;
16241633
try {
1625-
if (!(query instanceof CreateDatabase) && !initialize()) {
1634+
if (!(query instanceof CreateDatabase) && !(query instanceof DropDatabase) &&
1635+
!initialize()) {
16261636
lasterror = new BSimError(ErrorCategory.Nodatabase, "The database does not exist");
16271637
return null;
16281638
}
@@ -2087,6 +2097,29 @@ private void fdbQueryChildren(QueryChildren query) throws LSHException, SQLExcep
20872097
}
20882098
}
20892099

2100+
private void fdbDatabaseDrop(DropDatabase query) throws LSHException {
2101+
ResponseDropDatabase response = query.getResponse();
2102+
if (query.databaseName == null) {
2103+
throw new LSHException("Missing databaseName for drop database");
2104+
}
2105+
if (!query.databaseName.equals(ds.getServerInfo().getDBName())) {
2106+
throw new UnsupportedOperationException("drop database name must match");
2107+
}
2108+
response.dropSuccessful = true; // Response parameters assuming success
2109+
response.errorMessage = null;
2110+
try {
2111+
dropDatabase();
2112+
}
2113+
catch (SQLException e) {
2114+
String msg = e.getMessage();
2115+
if (msg.indexOf("database \"" + query.databaseName + "\" does not exist") > 0) {
2116+
return; // missing database
2117+
}
2118+
response.dropSuccessful = false;
2119+
response.errorMessage = e.getMessage();
2120+
}
2121+
}
2122+
20902123
/**
20912124
* Entry point for the CreateDatabase command
20922125
* @param query the query to execute

Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/PostgresFunctionDatabase.java

+59-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import ghidra.features.bsim.query.client.tables.SQLStringTable;
3232
import ghidra.features.bsim.query.description.*;
3333
import ghidra.features.bsim.query.protocol.*;
34+
import ghidra.util.Msg;
3435

3536
/**
3637
* Defines the BSim {@link FunctionDatabase} backed by a PostgreSQL database.
@@ -200,9 +201,6 @@ protected void generateRawDatabase() throws SQLException {
200201
st.executeUpdate(createdbstring);
201202
postgresDs.initializeFrom(defaultDs);
202203
}
203-
finally {
204-
defaultDs.dispose();
205-
}
206204
}
207205

208206
@Override
@@ -244,6 +242,64 @@ protected void createDatabase(Configuration config) throws SQLException {
244242
}
245243
}
246244

245+
@Override
246+
protected void dropDatabase() throws SQLException {
247+
248+
if (getStatus() == Status.Busy || postgresDs.getActiveConnections() != 0) {
249+
throw new SQLException("database in use");
250+
}
251+
252+
BSimServerInfo serverInfo = postgresDs.getServerInfo();
253+
BSimServerInfo defaultServerInfo =
254+
new BSimServerInfo(DBType.postgres, serverInfo.getUserInfo(),
255+
serverInfo.getServerName(), serverInfo.getPort(), DEFAULT_DATABASE_NAME);
256+
257+
BSimPostgresDataSource defaultDs =
258+
BSimPostgresDBConnectionManager.getDataSource(defaultServerInfo);
259+
if (getStatus() == Status.Ready) {
260+
defaultDs.initializeFrom(postgresDs);
261+
}
262+
263+
close(); // close this instance
264+
265+
try (Connection defaultDb = defaultDs.getConnection();
266+
Statement defaultSt = defaultDb.createStatement()) {
267+
try (ResultSet rs = defaultSt.executeQuery(
268+
"SELECT 1 FROM pg_database WHERE datname='" + serverInfo.getDBName() + "'")) {
269+
if (!rs.next()) {
270+
return; // database does not exist
271+
}
272+
}
273+
274+
// Connect to database and examine schema
275+
HashSet<String> tableNames = new HashSet<>();
276+
postgresDs.initializeFrom(defaultDs);
277+
try (Connection c = initConnection(); Statement st = c.createStatement()) {
278+
try (ResultSet rs = st.executeQuery(
279+
"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name")) {
280+
while (rs.next()) {
281+
tableNames.add(rs.getString(1));
282+
}
283+
}
284+
}
285+
286+
// Spot check for a few BSim table names that always exist
287+
if (!tableNames.contains("keyvaluetable") || !tableNames.contains("desctable") ||
288+
!tableNames.contains("weighttable")) {
289+
throw new SQLException("attempted to drop non-BSim database");
290+
}
291+
292+
postgresDs.dispose(); // disconnect before dropping database
293+
294+
Msg.info(this, "Dropping BSim postgresql database: " + serverInfo);
295+
defaultSt.executeUpdate("DROP DATABASE \"" + serverInfo.getDBName() + '"');
296+
}
297+
finally {
298+
// ensure
299+
postgresDs.initializeFrom(defaultDs);
300+
}
301+
}
302+
247303
/**
248304
*
249305
* @throws SQLException if there is a problem creating or executing the query

0 commit comments

Comments
 (0)