fix(database): migrate H2 safely and protect backup restores - #7207
fix(database): migrate H2 safely and protect backup restores#7207Ludy87 wants to merge 6 commits into
Conversation
Add automated migration from legacy H2 2.3.232 on-disk DBs to H2 2.4.240: new H2DatabaseMigration class exports the old DB with a bundled 2.3 driver and imports into a new 2.4 database, invoked reflectively from SPDFApplication. Build and resources updated to bundle the old H2 driver for migration; default datasource names/URLs updated to the 2.4 filename. Harden DatabaseService import flow: verify backups, create a pre-restore safety backup, run import and restore on failure (propagating IOException). Minor fixes: DatabaseController temp-file cleanup, updated tests covering migration and import rollback, updated migration test script and fixture README.
Restrict jacocoReport to the project's compiled application classes and source dirs to avoid analysing embedded migration/dependency classes that appear in SourceSetOutput. Sets classDirectories to sourceSets.main.output.classesDirs and sourceDirectories to sourceSets.main.allSource.srcDirs so coverage only covers app code (keeps the existing dependsOn(test) and report settings).
| printStartupLogs(); | ||
| } | ||
|
|
||
| private static void migrateLegacyH2Database() throws IOException { |
There was a problem hiding this comment.
Introduced reflective startup of H2 migration via Class.forName/method.invoke; prefer explicit wiring to keep startup behaviour transparent
Details
✨ AI Reasoning
The code attempts to run an optional migration class by loading it reflectively and invoking its migrateIfNeeded method. Reflection and dynamic invocation can obscure behavior from static analysis and reviewers because the class may be absent in some builds (caught ClassNotFoundException) and the invocation path is not visible in normal call graphs. This construct changes startup semantics and was added in this change set, increasing the use of reflection in startup flow which can be used to hide or dynamically alter behavior.
🔧 How do I fix it?
Ensure code is transparent and not intentionally obfuscated. Avoid hiding functionality from code review. Focus on intent and deception, not specific patterns.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
| + database.toAbsolutePath() | ||
| + ";IFEXISTS=TRUE;ACCESS_MODE_DATA=r;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL"; | ||
| ClassLoader previous = Thread.currentThread().getContextClassLoader(); | ||
| try (URLClassLoader loader = |
There was a problem hiding this comment.
Uses URLClassLoader + Thread.setContextClassLoader + reflective invocation of org.h2.tools.Script.process; dynamic loading obscures runtime behavior
Details
✨ AI Reasoning
The migration class extracts a bundled legacy H2 JAR to a temp file, creates a URLClassLoader over it, sets it as the thread context class loader, and then reflectively looks up and invokes org.h2.tools.Script.process. These steps intentionally divert classloading and invocation into a dynamically-loaded JAR, making it harder to inspect via static analysis and obscuring the executed code path. This exact mechanism was added by the PR, increasing obfuscation-like patterns.
🔧 How do I fix it?
Ensure code is transparent and not intentionally obfuscated. Avoid hiding functionality from code review. Focus on intent and deception, not specific patterns.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
✅ Backend License Check PassedAll backend dependencies have valid and allowed licenses. The backend license report has been updated successfully. |
🚀 V2 Auto-Deployment Complete!🔗 Direct Test URL (non-SSL) http://54.175.155.236:7207 🧩 Admin portal included - try it at http://54.175.155.236:7207/portal. This deployment will be automatically cleaned up when the PR is closed. 🔄 Auto-deployed for approved V2 contributors. |
Description of Changes
configs/backupuntouched.:proprietary:check, blocking CI when runtime or migration-driver H2 versions differ from the reviewed lock.The change was made because H2 2.4 uses an incompatible database file format compared with H2 2.3. Existing installations and historical backups must remain recoverable during the upgrade.
Checklist
General
Documentation
Translations (if applicable)
scripts/counter_translation.pyUI Changes (if applicable)
Testing (if applicable)
task checkto verify linters, typechecks, and tests pass