strip only the trailing extension when deriving the h2 database name

This commit is contained in:
Craig Raw
2026-08-20 13:27:20 +02:00
parent 6cda110e28
commit bad92ba6e9
2 changed files with 23 additions and 2 deletions
@@ -933,10 +933,15 @@ public class DbPersistence implements Persistence {
}
private String getUrl(File walletFile, String password) throws StorageException {
if(JDBC_URL_INJECTION_PATTERN.matcher(walletFile.getAbsolutePath()).find()) {
File dbFile = walletFile.getAbsoluteFile();
if(JDBC_URL_INJECTION_PATTERN.matcher(dbFile.getPath()).find()) {
throw new StorageException("Wallet file path contains invalid characters");
}
return "jdbc:h2:" + walletFile.getAbsolutePath().replace("." + getType().getExtension(), "") + ";INIT=SET TRACE_LEVEL_FILE=4;TRACE_LEVEL_FILE=4;DEFRAG_ALWAYS=true;MAX_COMPACT_TIME=5000;DATABASE_TO_UPPER=false" + (password == null ? "" : ";CIPHER=AES");
//H2 appends the extension to the database name in the URL, so only a trailing extension can be removed - removing every occurrence would
//open a different file to the one tracked here, as would removing one from a directory name
File dbName = new File(dbFile.getParentFile(), getWalletName(dbFile, null));
return "jdbc:h2:" + dbName.getPath() + ";INIT=SET TRACE_LEVEL_FILE=4;TRACE_LEVEL_FILE=4;DEFRAG_ALWAYS=true;MAX_COMPACT_TIME=5000;DATABASE_TO_UPPER=false" + (password == null ? "" : ";CIPHER=AES");
}
private boolean persistsFor(Wallet wallet) {
@@ -175,6 +175,22 @@ public class DbPersistenceTest {
Assertions.assertTrue(new Storage(PersistenceType.DB, storage.getWalletFile()).loadEncryptedWallet("pass").getWallet().isValid());
}
@Test
public void walletNameContainingExtensionUsesItsOwnFile() throws Exception {
Storage otherStorage = createUnencryptedWallet("backup2");
otherStorage.closeAndWait();
File otherFile = otherStorage.getWalletFile();
Sha256Hash otherHash = getFileHash(otherFile);
//The file for this wallet is backup.mv.db2.mv.db - removing every occurrence of the extension from the path yields the database name backup2
Storage storage = createUnencryptedWallet("backup.mv.db2");
storage.closeAndWait();
Assertions.assertTrue(storage.getWalletFile().exists(), "wallet was written to a file other than the one tracked");
Assertions.assertTrue(new Storage(PersistenceType.DB, storage.getWalletFile()).loadUnencryptedWallet().getWallet().isValid());
Assertions.assertEquals(otherHash, getFileHash(otherFile), "another wallet file was written by a wallet name containing the extension");
}
@Test
public void passwordRemovalDecryptsWalletFile() throws Exception {
Storage storage = createUnencryptedWallet("Savings");