diff --git a/src/main/java/org/sqlite/SQLiteConfig.java b/src/main/java/org/sqlite/SQLiteConfig.java index 9ae263227..b54bb4ca4 100644 --- a/src/main/java/org/sqlite/SQLiteConfig.java +++ b/src/main/java/org/sqlite/SQLiteConfig.java @@ -117,11 +117,56 @@ 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.isEmpty() && !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,68 +208,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 { - if (pragmaTable.containsKey(Pragma.PASSWORD.pragmaName)) { - 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("'", "''"))); - stat.execute("select 1 from sqlite_schema"); - } - } - - 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)); - } - } - } 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; } /** @@ -307,7 +331,20 @@ 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); } /**