Skip to content

fix(jdbc): quote savepoint name before interpolating into sql - #1487

Merged
gotson merged 2 commits into
xerial:masterfrom
sahvx655-wq:savepoint-name-quote
Oct 27, 2026
Merged

gotson merged 2 commits into
xerial:masterfrom
sahvx655-wq:savepoint-name-quote

Conversation

@sahvx655-wq

Copy link
Copy Markdown
Contributor

Unquoted savepoint name in SAVEPOINT/RELEASE/ROLLBACK statements

JDBC3Connection builds the savepoint statements with String.format("SAVEPOINT %s", ...) and hands the result straight to DB.exec, so the name supplied to Connection.setSavepoint(String) lands in an identifier position of the generated SQL with no quoting. I came across this while tracing where application supplied strings reach exec: unlike the metadata queries that were hardened earlier, the four savepoint sites interpolate the name verbatim. Any name that is not a bare SQLite token therefore corrupts the statement. A name such as a b or a"b throws at prepare time (SQLITE_ERROR ... unrecognized token/syntax error), and because getSavepointName() keeps the original string, the later RELEASE/ROLLBACK TO for the same savepoint is mis-generated as well.

The root cause is the missing identifier quoting, not the caller. DB.exec prepares a single statement, so a trailing ; ... is discarded rather than executed, which keeps this short of stacked-query execution, but the name still breaks out of the identifier it was meant to be and quietly changes which statement SQLite compiles. It is the same class of unescaped user input in SQL that the metadata getters carried, and it is addressed the same way, by quoting the value where it is used. The patch wraps the name as a double quoted SQLite identifier (doubling any embedded double quote) at all four build sites, so a name is always treated as one identifier and round-trips cleanly through rollback and release. The generated SQLITE_SAVEPOINT_<id> form is unaffected, since quoting an already-valid identifier is a no-op in SQLite. Left unfixed, callers that derive savepoint names from external input hit spurious failures and unpredictable transaction control. The added SavepointTest case fails on the current tree and passes with the fix.

Comment thread src/main/java/org/sqlite/jdbc3/JDBC3Connection.java Outdated
@gotson
gotson merged commit 6e26d10 into xerial:master Oct 27, 2026
32 checks passed
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.

2 participants