@@ -73,6 +73,13 @@ using v8::Value;
7373
7474inline MaybeLocal<String> Utf8StringMaybeOneByte (Isolate* isolate,
7575 std::string_view input) {
76+ // SQLITE_MAX_LENGTH exceeds String::kMaxLength, and V8 returns an empty
77+ // handle without throwing. Raise the error here or the value is dropped.
78+ if (input.size () > static_cast <size_t >(String::kMaxLength )) [[unlikely]] {
79+ isolate->ThrowException (node::ERR_STRING_TOO_LONG (isolate));
80+ return MaybeLocal<String>();
81+ }
82+
7683 const int len = static_cast <int >(input.size ());
7784 if (simdutf::validate_ascii (input.data (), input.size ())) {
7885 return String::NewFromOneByte (
@@ -351,7 +358,11 @@ class Database;
351358inline void THROW_ERR_SQLITE_ERROR (Isolate* isolate, Database* db) {
352359 if (db->ShouldIgnoreSQLiteError ()) {
353360 db->SetIgnoreNextSQLiteError (false );
354- return ;
361+ // Suppression that swallows no pending exception would also swallow the
362+ // SQLite error, reporting a failed statement as a success.
363+ if (isolate->HasPendingException ()) {
364+ return ;
365+ }
355366 }
356367
357368 Local<Object> e;
@@ -971,8 +982,7 @@ Intercepted DatabaseLimits::LimitsSetter(
971982 }
972983 }
973984
974- sqlite3_limit (
975- limits->database_ ->Connection (), limit_info->sqlite_limit_id , new_value);
985+ limits->database_ ->SetLimit (limit_info->sqlite_limit_id , new_value);
976986 return Intercepted::kYes ;
977987}
978988
@@ -1190,6 +1200,7 @@ int VirtualTableModule::xBestIndex(sqlite3_vtab* pVTab,
11901200 for (int hidden_idx = 0 ; hidden_idx < num_hidden; hidden_idx++) {
11911201 int col = mod->hidden_col_indices_ [hidden_idx];
11921202
1203+ int args_before = argv_index;
11931204 for (int i = 0 ; i < pInfo->nConstraint ; i++) {
11941205 if (pInfo->aConstraint [i].iColumn == col &&
11951206 pInfo->aConstraint [i].usable &&
@@ -1204,6 +1215,20 @@ int VirtualTableModule::xBestIndex(sqlite3_vtab* pVTab,
12041215 break ;
12051216 }
12061217 }
1218+
1219+ // No usable constraint means the query supplied a parameter whose value is
1220+ // not available at this point in the plan. Accepting it would pass null to
1221+ // rows() and silently return empty results, so reject the plan and let
1222+ // SQLite pick a different ordering instead.
1223+ // https://www.sqlite.org/vtab.html#enforcing_required_parameters_on_table_valued_functions
1224+ if (argv_index == args_before) {
1225+ for (int i = 0 ; i < pInfo->nConstraint ; i++) {
1226+ if (pInfo->aConstraint [i].iColumn == col &&
1227+ pInfo->aConstraint [i].op == SQLITE_INDEX_CONSTRAINT_EQ ) {
1228+ return SQLITE_CONSTRAINT ;
1229+ }
1230+ }
1231+ }
12071232 }
12081233
12091234 if (!idx_str.empty ()) {
@@ -1650,15 +1675,14 @@ bool Database::Open() {
16501675
16511676 sqlite3_busy_timeout (connection_.get (), open_config_.get_timeout ());
16521677
1653- // Apply initial limits
16541678 for (const auto & [js_name, sqlite_limit_id] : kLimitMapping ) {
1655- const auto & limit_value = open_config_.initial_limits ()[sqlite_limit_id];
1679+ const auto & limit_value = open_config_.limits ()[sqlite_limit_id];
16561680 if (limit_value.has_value ()) {
16571681 sqlite3_limit (connection_.get (), sqlite_limit_id, *limit_value);
16581682 }
16591683 }
16601684
1661- if (allow_load_extension_ ) {
1685+ if (enable_load_extension_ ) {
16621686 if (env ()->permission ()->enabled ()) [[unlikely]] {
16631687 THROW_ERR_LOAD_SQLITE_EXTENSION (env (),
16641688 " Cannot load SQLite extensions when the "
@@ -1677,6 +1701,15 @@ bool Database::Open() {
16771701 connection_.get (), SQLITE_TRACE_PROFILE , TraceCallback, this );
16781702 }
16791703
1704+ // The authorizer outlives the connection, so reopening must reinstall it.
1705+ Local<Value> authorizer =
1706+ object ()->GetInternalField (kAuthorizerCallback ).template As <Value>();
1707+ if (authorizer->IsFunction ()) {
1708+ r = sqlite3_set_authorizer (
1709+ connection_.get (), Database::AuthorizerCallback, this );
1710+ CHECK_ERROR_OR_THROW (env ()->isolate (), this , r, SQLITE_OK , false );
1711+ }
1712+
16801713 opened = true ;
16811714 return true ;
16821715}
@@ -1724,6 +1757,11 @@ inline sqlite3* Database::Connection() {
17241757 return connection_.get ();
17251758}
17261759
1760+ void Database::SetLimit (int sqlite_limit_id, int value) {
1761+ sqlite3_limit (connection_.get (), sqlite_limit_id, value);
1762+ open_config_.set_limit (sqlite_limit_id, value);
1763+ }
1764+
17271765void Database::SetIgnoreNextSQLiteError (bool ignore) {
17281766 ignore_next_sqlite_error_ = ignore;
17291767}
@@ -2069,7 +2107,7 @@ void Database::New(const FunctionCallbackInfo<Value>& args) {
20692107 return ;
20702108 }
20712109
2072- open_config.set_initial_limit (sqlite_limit_id, limit_val);
2110+ open_config.set_limit (sqlite_limit_id, limit_val);
20732111 }
20742112 }
20752113 }
@@ -2171,9 +2209,7 @@ void Database::Prepare(const FunctionCallbackInfo<Value>& args) {
21712209 Local<Object> options = args[1 ].As <Object>();
21722210
21732211 Local<Value> return_arrays_v;
2174- if (!options
2175- ->Get (env->context (),
2176- FIXED_ONE_BYTE_STRING (env->isolate (), " returnArrays" ))
2212+ if (!options->Get (env->context (), env->return_arrays_string ())
21772213 .ToLocal (&return_arrays_v)) {
21782214 return ;
21792215 }
@@ -2188,9 +2224,7 @@ void Database::Prepare(const FunctionCallbackInfo<Value>& args) {
21882224 }
21892225
21902226 Local<Value> read_big_ints_v;
2191- if (!options
2192- ->Get (env->context (),
2193- FIXED_ONE_BYTE_STRING (env->isolate (), " readBigInts" ))
2227+ if (!options->Get (env->context (), env->read_bigints_string ())
21942228 .ToLocal (&read_big_ints_v)) {
21952229 return ;
21962230 }
@@ -2205,10 +2239,7 @@ void Database::Prepare(const FunctionCallbackInfo<Value>& args) {
22052239 }
22062240
22072241 Local<Value> allow_bare_named_params_v;
2208- if (!options
2209- ->Get (env->context (),
2210- FIXED_ONE_BYTE_STRING (env->isolate (),
2211- " allowBareNamedParameters" ))
2242+ if (!options->Get (env->context (), env->allow_bare_named_params_string ())
22122243 .ToLocal (&allow_bare_named_params_v)) {
22132244 return ;
22142245 }
@@ -2224,10 +2255,7 @@ void Database::Prepare(const FunctionCallbackInfo<Value>& args) {
22242255 }
22252256
22262257 Local<Value> allow_unknown_named_params_v;
2227- if (!options
2228- ->Get (env->context (),
2229- FIXED_ONE_BYTE_STRING (env->isolate (),
2230- " allowUnknownNamedParameters" ))
2258+ if (!options->Get (env->context (), env->allow_unknown_named_params_string ())
22312259 .ToLocal (&allow_unknown_named_params_v)) {
22322260 return ;
22332261 }
@@ -5338,10 +5366,8 @@ static void Initialize(Local<Object> target,
53385366 db_tmpl,
53395367 FIXED_ONE_BYTE_STRING (isolate, " isTransaction" ),
53405368 Database::IsTransactionGetter);
5341- SetSideEffectFreeGetter (isolate,
5342- db_tmpl,
5343- FIXED_ONE_BYTE_STRING (isolate, " limits" ),
5344- Database::LimitsGetter);
5369+ SetSideEffectFreeGetter (
5370+ isolate, db_tmpl, env->limits_string (), Database::LimitsGetter);
53455371 Local<String> sqlite_type_key = FIXED_ONE_BYTE_STRING (isolate, " sqlite-type" );
53465372 Local<v8::Symbol> sqlite_type_symbol =
53475373 v8::Symbol::For (isolate, sqlite_type_key);
0 commit comments