Skip to content

Implemented API support for set_limit (sqlite3_limit) in sqlite#4975

Open
LucaCappelletti94 wants to merge 1 commit intodiesel-rs:mainfrom
LucaCappelletti94:sqlite3_limit
Open

Implemented API support for set_limit (sqlite3_limit) in sqlite#4975
LucaCappelletti94 wants to merge 1 commit intodiesel-rs:mainfrom
LucaCappelletti94:sqlite3_limit

Conversation

@LucaCappelletti94
Copy link
Contributor

This PR exposes SQLite's sqlite3_limit API through new methods on SqliteConnection. It is another PR in the series of: "let's make more of SQLite usable with Diesel in frontend WASM development", but it really applies to many other cases.

Motivation

SQLite's security documentation explicitly recommends using sqlite3_limit() for hardening:

Reduce the limits that SQLite imposes on inputs. This can help prevent denial of service attacks and other kinds of mischief that can occur as a result of unusually large inputs. You can do this either at compile-time using -DSQLITE_MAX_... options, or at run-time using the sqlite3_limit() interface.

The documentation also notes: "Most applications can reduce limits dramatically without impacting functionality."

SQLite's limits documentation provides specific context:

  • CompoundSelect: Defaults to 500, but "in practice we almost never see the number of terms in a compound select exceed single digits"
  • ExprDepth: Can prevent stack exhaustion from deeply nested expressions
  • SqlLength: The security page suggests reducing from 1,000,000,000 to 100,000 for high-security deployments

While users could technically call the FFI directly, this PR provides a safe, ergonomic, and documented API that makes following SQLite's security recommendations straightforward.

Usage

Apply all recommended security limits in one call:

use diesel::sqlite::{SqliteConnection, SqliteLimit};
use diesel::Connection;

let mut conn = SqliteConnection::establish(":memory:")?;

// Apply SQLite's recommended high-security limits
conn.set_recommended_security_limits();

// Relax specific limits if needed for your application
conn.set_limit(SqliteLimit::VariableNumber, 999);

Or configure individual limits:

use diesel::sqlite::{SqliteConnection, SqliteLimit};
use diesel::Connection;

let mut conn = SqliteConnection::establish(":memory:")?;

// Limit SQL statement length to 100KB
conn.set_limit(SqliteLimit::SqlLength, 100_000);

// Prevent ReDoS via LIKE patterns
conn.set_limit(SqliteLimit::LikePatternLength, 100);

// Query current limits
let expr_depth = conn.get_limit(SqliteLimit::ExprDepth);

@LucaCappelletti94
Copy link
Contributor Author

LucaCappelletti94 commented Feb 14, 2026

The compile test failures (mysql_on_conflict_tests.rs, pg_on_conflict_requires_valid_conflict_target.rs, update_requires_left_side_of_eq_to_be_a_column.rs) seem to be pre-existing on main and unrelated to this PR. They're caused by rustc error message formatting changes (e.g., Column vs diesel::Column in trait bounds).

I will do a quick separate PR to fix them later if that is correct and they are unrelated to this PR.

@LucaCappelletti94 LucaCappelletti94 marked this pull request as ready for review February 14, 2026 11:36
@weiznich weiznich requested a review from a team February 15, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant