diff --git a/src/workerd/api/sql-test.js b/src/workerd/api/sql-test.js index 328845080e8..0f70f58783a 100644 --- a/src/workerd/api/sql-test.js +++ b/src/workerd/api/sql-test.js @@ -238,6 +238,21 @@ async function test(storage) { 'Error: Wrong number of parameter bindings for SQL query.' ) + // Prepared statement with whitespace + const whitespace = [' ', '\t', '\n', '\r', '\v', '\f', '\r\n'] + + for (const char of whitespace) { + const prepared = sql.prepare(`SELECT 1;${char}`); + const result = [...prepared()] + + assert.equal(result.length, 1) + } + + // Prepared statement with multiple statements + assert.throws(() => { + sql.prepare('SELECT 1; SELECT 2;'); + }, /A prepared SQL statement must contain only one statement./) + // Accessing a hidden _cf_ table assert.throws( () => sql.exec('CREATE TABLE _cf_invalid (name TEXT)'), diff --git a/src/workerd/util/sqlite.c++ b/src/workerd/util/sqlite.c++ index f0e2f3d72bb..4894ec701b8 100644 --- a/src/workerd/util/sqlite.c++ +++ b/src/workerd/util/sqlite.c++ @@ -399,7 +399,7 @@ kj::Own SqliteDatabase::prepareSql( SQLITE_REQUIRE(result != nullptr, "SQL code did not contain a statement.", sqlCode); auto ownResult = ownSqlite(result); - while (*tail == ' ' || *tail == '\n') ++tail; + while (*tail == ' ' || *tail == '\t' || *tail == '\n' || *tail == '\r' || *tail == '\v' || *tail == '\f') ++tail; switch (multi) { case SINGLE: