From 6fbf972be2603efe8574e0bb8765988985c26f44 Mon Sep 17 00:00:00 2001 From: h8leet Date: Wed, 29 Apr 2026 01:29:59 +0300 Subject: [PATCH 1/4] fix: SELECT statement before all pragmas applied --- src/main/java/org/sqlite/SQLiteConfig.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/sqlite/SQLiteConfig.java b/src/main/java/org/sqlite/SQLiteConfig.java index 9ae263227..342b5f7af 100644 --- a/src/main/java/org/sqlite/SQLiteConfig.java +++ b/src/main/java/org/sqlite/SQLiteConfig.java @@ -192,7 +192,8 @@ public void apply(Connection conn) throws SQLException { Statement stat = conn.createStatement(); try { - if (pragmaTable.containsKey(Pragma.PASSWORD.pragmaName)) { + boolean hasPasswordPragma = pragmaTable.containsKey(Pragma.PASSWORD.pragmaName); + if (hasPasswordPragma) { String password = pragmaTable.getProperty(Pragma.PASSWORD.pragmaName); if (password != null && !password.isEmpty()) { String hexkeyMode = pragmaTable.getProperty(Pragma.HEXKEY_MODE.pragmaName); @@ -205,7 +206,6 @@ public void apply(Connection conn) throws SQLException { passwordPragma = "pragma key = '%s'"; } stat.execute(String.format(passwordPragma, password.replace("'", "''"))); - stat.execute("select 1 from sqlite_schema"); } } @@ -220,6 +220,11 @@ public void apply(Connection conn) throws SQLException { stat.execute(String.format("pragma %s=%s", key, value)); } } + + // password validation + if (hasPasswordPragma) { + stat.execute("select 1 from sqlite_schema"); + } } finally { if (stat != null) { stat.close(); From e85c157d4ed8a30586c693f7bb16ca519b7f1395 Mon Sep 17 00:00:00 2001 From: h8leet Date: Wed, 29 Apr 2026 01:35:53 +0300 Subject: [PATCH 2/4] feat: allowed custom pragma names when org.sqlite.jdbc.pragma.validation is not equals ignore case "true" --- src/main/java/org/sqlite/SQLiteConfig.java | 165 ++++++++++++--------- 1 file changed, 97 insertions(+), 68 deletions(-) diff --git a/src/main/java/org/sqlite/SQLiteConfig.java b/src/main/java/org/sqlite/SQLiteConfig.java index 342b5f7af..84b1332b3 100644 --- a/src/main/java/org/sqlite/SQLiteConfig.java +++ b/src/main/java/org/sqlite/SQLiteConfig.java @@ -117,11 +117,54 @@ public Connection createConnection(String url) throws SQLException { */ public void apply(Connection conn) throws SQLException { - HashSet pragmaParams = new HashSet(); - for (Pragma each : Pragma.values()) { - pragmaParams.add(each.pragmaName); + applyLimits(conn); + + Set pragmaParams = allowedPragmaParams(); + Set restrictedPragmaParams = pragmaParams.isEmpty() ? restrictedPragmaParams() : new HashSet<>(); + + Statement stat = conn.createStatement(); + try { + boolean hasPasswordPragma = pragmaTable.containsKey(Pragma.PASSWORD.pragmaName); + if (hasPasswordPragma) { + String password = pragmaTable.getProperty(Pragma.PASSWORD.pragmaName); + if (password != null && !password.isEmpty()) { + String hexkeyMode = pragmaTable.getProperty(Pragma.HEXKEY_MODE.pragmaName); + String passwordPragma; + if (HexKeyMode.SSE.name().equalsIgnoreCase(hexkeyMode)) { + passwordPragma = "pragma hexkey = '%s'"; + } else if (HexKeyMode.SQLCIPHER.name().equalsIgnoreCase(hexkeyMode)) { + passwordPragma = "pragma key = \"x'%s'\""; + } else { + passwordPragma = "pragma key = '%s'"; + } + stat.execute(String.format(passwordPragma, password.replace("'", "''"))); + } + } + + for (Object each : pragmaTable.keySet()) { + String key = each.toString(); + if ((pragmaParams.isEmpty() && restrictedPragmaParams.contains(key)) || !pragmaParams.contains(key)) { + continue; + } + + String value = pragmaTable.getProperty(key); + if (value != null) { + stat.execute(String.format("pragma %s=%s", key, value)); + } + } + + // password validation + if (hasPasswordPragma) { + stat.execute("select 1 from sqlite_schema"); + } + } finally { + if (stat != null) { + stat.close(); + } } + } + private void applyLimits(Connection conn) throws SQLException { if (conn instanceof SQLiteConnection) { SQLiteConnection sqliteConn = (SQLiteConnection) conn; sqliteConn.setLimit( @@ -163,73 +206,47 @@ public void apply(Connection conn) throws SQLException { SQLiteLimits.SQLITE_LIMIT_PAGE_COUNT, parseLimitPragma(Pragma.LIMIT_PAGE_COUNT, DEFAULT_MAX_PAGE_COUNT)); } + } - pragmaParams.remove(Pragma.OPEN_MODE.pragmaName); - pragmaParams.remove(Pragma.SHARED_CACHE.pragmaName); - pragmaParams.remove(Pragma.LOAD_EXTENSION.pragmaName); - pragmaParams.remove(Pragma.DATE_PRECISION.pragmaName); - pragmaParams.remove(Pragma.DATE_CLASS.pragmaName); - pragmaParams.remove(Pragma.DATE_STRING_FORMAT.pragmaName); - pragmaParams.remove(Pragma.PASSWORD.pragmaName); - pragmaParams.remove(Pragma.HEXKEY_MODE.pragmaName); - pragmaParams.remove(Pragma.LIMIT_ATTACHED.pragmaName); - pragmaParams.remove(Pragma.LIMIT_COLUMN.pragmaName); - pragmaParams.remove(Pragma.LIMIT_COMPOUND_SELECT.pragmaName); - pragmaParams.remove(Pragma.LIMIT_EXPR_DEPTH.pragmaName); - pragmaParams.remove(Pragma.LIMIT_FUNCTION_ARG.pragmaName); - pragmaParams.remove(Pragma.LIMIT_LENGTH.pragmaName); - pragmaParams.remove(Pragma.LIMIT_LIKE_PATTERN_LENGTH.pragmaName); - pragmaParams.remove(Pragma.LIMIT_SQL_LENGTH.pragmaName); - pragmaParams.remove(Pragma.LIMIT_TRIGGER_DEPTH.pragmaName); - pragmaParams.remove(Pragma.LIMIT_VARIABLE_NUMBER.pragmaName); - pragmaParams.remove(Pragma.LIMIT_VDBE_OP.pragmaName); - pragmaParams.remove(Pragma.LIMIT_WORKER_THREADS.pragmaName); - pragmaParams.remove(Pragma.LIMIT_PAGE_COUNT.pragmaName); - - // exclude this "fake" pragma from execution - pragmaParams.remove(Pragma.JDBC_EXPLICIT_READONLY.pragmaName); - pragmaParams.remove(Pragma.JDBC_GET_GENERATED_KEYS.pragmaName); - - Statement stat = conn.createStatement(); - try { - boolean hasPasswordPragma = pragmaTable.containsKey(Pragma.PASSWORD.pragmaName); - if (hasPasswordPragma) { - String password = pragmaTable.getProperty(Pragma.PASSWORD.pragmaName); - if (password != null && !password.isEmpty()) { - String hexkeyMode = pragmaTable.getProperty(Pragma.HEXKEY_MODE.pragmaName); - String passwordPragma; - if (HexKeyMode.SSE.name().equalsIgnoreCase(hexkeyMode)) { - passwordPragma = "pragma hexkey = '%s'"; - } else if (HexKeyMode.SQLCIPHER.name().equalsIgnoreCase(hexkeyMode)) { - passwordPragma = "pragma key = \"x'%s'\""; - } else { - passwordPragma = "pragma key = '%s'"; - } - stat.execute(String.format(passwordPragma, password.replace("'", "''"))); - } - } - - for (Object each : pragmaTable.keySet()) { - String key = each.toString(); - if (!pragmaParams.contains(key)) { - continue; - } - - String value = pragmaTable.getProperty(key); - if (value != null) { - stat.execute(String.format("pragma %s=%s", key, value)); - } - } - - // password validation - if (hasPasswordPragma) { - stat.execute("select 1 from sqlite_schema"); - } - } finally { - if (stat != null) { - stat.close(); + private Set allowedPragmaParams() { + HashSet pragmaParams = new HashSet<>(); + if (Boolean.parseBoolean(System.getProperty("org.sqlite.jdbc.pragma.validation", "true"))) { + for (Pragma each : Pragma.values()) { + pragmaParams.add(each.pragmaName); } + pragmaParams.removeAll(restrictedPragmaParams()); } + return pragmaParams; + } + + private Set restrictedPragmaParams() { + HashSet pragmaParams = new HashSet<>(); + pragmaParams.add(Pragma.OPEN_MODE.pragmaName); + pragmaParams.add(Pragma.SHARED_CACHE.pragmaName); + pragmaParams.add(Pragma.LOAD_EXTENSION.pragmaName); + pragmaParams.add(Pragma.DATE_PRECISION.pragmaName); + pragmaParams.add(Pragma.DATE_CLASS.pragmaName); + pragmaParams.add(Pragma.DATE_STRING_FORMAT.pragmaName); + pragmaParams.add(Pragma.PASSWORD.pragmaName); + pragmaParams.add(Pragma.HEXKEY_MODE.pragmaName); + pragmaParams.add(Pragma.LIMIT_ATTACHED.pragmaName); + pragmaParams.add(Pragma.LIMIT_COLUMN.pragmaName); + pragmaParams.add(Pragma.LIMIT_COMPOUND_SELECT.pragmaName); + pragmaParams.add(Pragma.LIMIT_EXPR_DEPTH.pragmaName); + pragmaParams.add(Pragma.LIMIT_FUNCTION_ARG.pragmaName); + pragmaParams.add(Pragma.LIMIT_LENGTH.pragmaName); + pragmaParams.add(Pragma.LIMIT_LIKE_PATTERN_LENGTH.pragmaName); + pragmaParams.add(Pragma.LIMIT_SQL_LENGTH.pragmaName); + pragmaParams.add(Pragma.LIMIT_TRIGGER_DEPTH.pragmaName); + pragmaParams.add(Pragma.LIMIT_VARIABLE_NUMBER.pragmaName); + pragmaParams.add(Pragma.LIMIT_VDBE_OP.pragmaName); + pragmaParams.add(Pragma.LIMIT_WORKER_THREADS.pragmaName); + pragmaParams.add(Pragma.LIMIT_PAGE_COUNT.pragmaName); + + // exclude this "fake" pragma from execution + pragmaParams.add(Pragma.JDBC_EXPLICIT_READONLY.pragmaName); + pragmaParams.add(Pragma.JDBC_GET_GENERATED_KEYS.pragmaName); + return pragmaParams; } /** @@ -312,7 +329,19 @@ public int getOpenModeFlags() { * @param value The value to set it to. */ public void setPragma(Pragma pragma, String value) { - pragmaTable.put(pragma.pragmaName, value); + setPragma(pragma.pragmaName, value); + } + + /** + *

Sets a pragma's value.

+ *

Pragma name not from the {@link Pragma#values()} is allowed when "-Dorg.sqlite.jdbc.pragma.validation" + * value is not equals ignore case "true".

+ * + * @param pragmaName The pragma name to change. + * @param value The value to set it to. + */ + public void setPragma(String pragmaName, String value) { + pragmaTable.put(pragmaName, value); } /** From 16a20f8e2fde8371b33cddfb715b015e0d044b42 Mon Sep 17 00:00:00 2001 From: h8leet Date: Wed, 29 Apr 2026 02:29:25 +0300 Subject: [PATCH 3/4] style: apply format rules --- src/main/java/org/sqlite/SQLiteConfig.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/sqlite/SQLiteConfig.java b/src/main/java/org/sqlite/SQLiteConfig.java index 84b1332b3..9727a1f61 100644 --- a/src/main/java/org/sqlite/SQLiteConfig.java +++ b/src/main/java/org/sqlite/SQLiteConfig.java @@ -120,7 +120,8 @@ public void apply(Connection conn) throws SQLException { applyLimits(conn); Set pragmaParams = allowedPragmaParams(); - Set restrictedPragmaParams = pragmaParams.isEmpty() ? restrictedPragmaParams() : new HashSet<>(); + Set restrictedPragmaParams = + pragmaParams.isEmpty() ? restrictedPragmaParams() : new HashSet<>(); Statement stat = conn.createStatement(); try { @@ -143,7 +144,8 @@ public void apply(Connection conn) throws SQLException { for (Object each : pragmaTable.keySet()) { String key = each.toString(); - if ((pragmaParams.isEmpty() && restrictedPragmaParams.contains(key)) || !pragmaParams.contains(key)) { + if ((pragmaParams.isEmpty() && restrictedPragmaParams.contains(key)) + || !pragmaParams.contains(key)) { continue; } @@ -333,9 +335,10 @@ public void setPragma(Pragma pragma, String value) { } /** - *

Sets a pragma's value.

- *

Pragma name not from the {@link Pragma#values()} is allowed when "-Dorg.sqlite.jdbc.pragma.validation" - * value is not equals ignore case "true".

+ * Sets a pragma's value. + * + *

Pragma name not from the {@link Pragma#values()} is allowed when + * "-Dorg.sqlite.jdbc.pragma.validation" value is not equals ignore case "true". * * @param pragmaName The pragma name to change. * @param value The value to set it to. From 1090caf41bc7fe28ff861692fd498d6e35c42924 Mon Sep 17 00:00:00 2001 From: h8leet Date: Thu, 30 Apr 2026 01:54:33 +0300 Subject: [PATCH 4/4] fix: checking of restricted pragmas --- src/main/java/org/sqlite/SQLiteConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/sqlite/SQLiteConfig.java b/src/main/java/org/sqlite/SQLiteConfig.java index 9727a1f61..b54bb4ca4 100644 --- a/src/main/java/org/sqlite/SQLiteConfig.java +++ b/src/main/java/org/sqlite/SQLiteConfig.java @@ -145,7 +145,7 @@ public void apply(Connection conn) throws SQLException { for (Object each : pragmaTable.keySet()) { String key = each.toString(); if ((pragmaParams.isEmpty() && restrictedPragmaParams.contains(key)) - || !pragmaParams.contains(key)) { + || (!pragmaParams.isEmpty() && !pragmaParams.contains(key))) { continue; }