Skip to content

Check sqlite3_bind return codes so extra parameters are not silently ignored #309

Description

@chrispader

Summary

All sqlite3_bind_*() return codes are ignored. Supplying more parameters than a statement declares returns SQLITE_RANGE, but NitroSQLite continues to step the statement successfully, silently discarding the extra values.

Verified on main at ad8b835 (v9.7.0) and independently reproduced against SQLite.

Code evidence

operations.cpp#L120-L143 calls sqlite3_bind_null, sqlite3_bind_int, sqlite3_bind_int64, sqlite3_bind_double, sqlite3_bind_text, and sqlite3_bind_blob without inspecting their return values.

prepareStatement() then returns the statement and execution proceeds normally.

Smallest reproducer

const db = open({ name: 'bind.sqlite' })

// The SQL has one parameter, but two values are supplied.
const result = db.execute('SELECT ? AS value', [7, 8])
console.log(result.rows.item(0)?.value)

Expected: reject the mismatched parameter list with a NitroSQLiteError/SQLITE_RANGE error.

Observed: the query succeeds with value = 7; the extra 8 is silently ignored.

Independent SQLite C API result for the same sequence:

sqlite3_bind_int(statement, 1, 7) -> 0  (SQLITE_OK)
sqlite3_bind_int(statement, 2, 8) -> 25 (SQLITE_RANGE)
sqlite3_step(statement)           -> 100 (SQLITE_ROW)
value                             -> 7

Impact

  • Query-builder, ORM, migration, and application bugs can silently bind the wrong parameter set instead of failing close to the source.
  • Batch commands can appear successful while extra values are discarded.
  • Other bind errors (for example allocation-related failures) are also ignored and may surface later with misleading behavior.

Acceptance criteria

  • Check every sqlite3_bind_*() return code and throw a normalized SQL execution error when it is not SQLITE_OK.
  • Include the parameter index and SQLite error text/code without logging parameter values.
  • Decide and document whether parameter count must match exactly using sqlite3_bind_parameter_count(); at minimum, extra parameters must never be silently accepted.
  • Apply the same behavior to sync, async, batch, and future prepared-statement APIs through a shared bind implementation.

Regression-test target

Tests asserting that SELECT ? with [7, 8] rejects for sync, async, and batch execution, while a correctly sized parameter list still succeeds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions