@@ -1840,8 +1840,12 @@ std::optional<std::string> ValidateDatabasePath(Environment* env,
18401840 } else if (path->IsObject ()) { // When is URL
18411841 auto url = path.As <Object>();
18421842 Local<Value> href;
1843- if (url->Get (env->context (), env->href_string ()).ToLocal (&href) &&
1844- href->IsString ()) {
1843+ // Let an exception thrown by the href getter propagate instead of
1844+ // replacing it with ERR_INVALID_ARG_TYPE.
1845+ if (!url->Get (env->context (), env->href_string ()).ToLocal (&href)) {
1846+ return std::nullopt ;
1847+ }
1848+ if (href->IsString ()) {
18451849 Utf8Value location_value (env->isolate (), href.As <String>());
18461850 auto location = location_value.ToStringView ();
18471851 if (!has_null_bytes (location)) {
@@ -3194,9 +3198,13 @@ void Database::CreateSession(const FunctionCallbackInfo<Value>& args) {
31943198
31953199void Backup (const FunctionCallbackInfo<Value>& args) {
31963200 Environment* env = Environment::GetCurrent (args);
3197- if (args.Length () < 1 || !args[0 ]->IsObject ()) {
3198- THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
3199- " The \" sourceDb\" argument must be an object." );
3201+ // Unlike the other unwrap sites in this file, which rely on V8's signature
3202+ // check for args.This(), this one takes a value out of args[] and so has to
3203+ // check the type itself before unwrapping it.
3204+ if (!Database::GetConstructorTemplate (env)->HasInstance (args[0 ])) {
3205+ THROW_ERR_INVALID_ARG_TYPE (
3206+ env->isolate (),
3207+ " The \" sourceDb\" argument must be an instance of Database." );
32003208 return ;
32013209 }
32023210
@@ -4606,6 +4614,54 @@ static inline void SetSideEffectFreeGetter(
46064614 name, getter, Local<FunctionTemplate>(), DontDelete);
46074615}
46084616
4617+ Local<FunctionTemplate> Database::GetConstructorTemplate (Environment* env) {
4618+ Local<FunctionTemplate> tmpl = env->sqlite_database_constructor_template ();
4619+ if (tmpl.IsEmpty ()) {
4620+ Isolate* isolate = env->isolate ();
4621+ tmpl = NewFunctionTemplate (isolate, Database::New);
4622+ tmpl->InstanceTemplate ()->SetInternalFieldCount (
4623+ Database::kInternalFieldCount );
4624+ SetProtoMethod (isolate, tmpl, " open" , Database::Open);
4625+ SetProtoMethod (isolate, tmpl, " close" , Database::Close);
4626+ SetProtoDispose (isolate, tmpl, Database::Dispose);
4627+ SetProtoMethod (isolate, tmpl, " prepare" , Database::Prepare);
4628+ SetProtoMethod (isolate, tmpl, " exec" , Database::Exec);
4629+ SetProtoMethod (isolate, tmpl, " function" , Database::CustomFunction);
4630+ SetProtoMethod (isolate, tmpl, " createTagStore" , Database::CreateTagStore);
4631+ SetProtoMethodNoSideEffect (isolate, tmpl, " location" , Database::Location);
4632+ SetProtoMethod (isolate, tmpl, " aggregate" , Database::AggregateFunction);
4633+ SetProtoMethod (isolate, tmpl, " createSession" , Database::CreateSession);
4634+ SetProtoMethod (isolate, tmpl, " applyChangeset" , Database::ApplyChangeset);
4635+ SetProtoMethod (
4636+ isolate, tmpl, " enableLoadExtension" , Database::EnableLoadExtension);
4637+ SetProtoMethod (isolate, tmpl, " enableDefensive" , Database::EnableDefensive);
4638+ SetProtoMethod (isolate, tmpl, " loadExtension" , Database::LoadExtension);
4639+ SetProtoMethod (isolate, tmpl, " serialize" , Database::Serialize);
4640+ SetProtoMethod (isolate, tmpl, " deserialize" , Database::Deserialize);
4641+ SetProtoMethod (isolate, tmpl, " setAuthorizer" , Database::SetAuthorizer);
4642+ SetProtoMethod (isolate, tmpl, " createModule" , Database::CreateModule);
4643+ SetSideEffectFreeGetter (isolate,
4644+ tmpl,
4645+ FIXED_ONE_BYTE_STRING (isolate, " isOpen" ),
4646+ Database::IsOpenGetter);
4647+ SetSideEffectFreeGetter (isolate,
4648+ tmpl,
4649+ FIXED_ONE_BYTE_STRING (isolate, " isTransaction" ),
4650+ Database::IsTransactionGetter);
4651+ SetSideEffectFreeGetter (
4652+ isolate, tmpl, env->limits_string (), Database::LimitsGetter);
4653+ Local<String> sqlite_type_key =
4654+ FIXED_ONE_BYTE_STRING (isolate, " sqlite-type" );
4655+ Local<v8::Symbol> sqlite_type_symbol =
4656+ v8::Symbol::For (isolate, sqlite_type_key);
4657+ Local<String> database_sync_string =
4658+ FIXED_ONE_BYTE_STRING (isolate, " node:sqlite" );
4659+ tmpl->InstanceTemplate ()->Set (sqlite_type_symbol, database_sync_string);
4660+ env->set_sqlite_database_constructor_template (tmpl);
4661+ }
4662+ return tmpl;
4663+ }
4664+
46094665SQLTagStore::~SQLTagStore () {}
46104666
46114667Local<FunctionTemplate> SQLTagStore::GetConstructorTemplate (Environment* env) {
@@ -5342,51 +5398,12 @@ static void Initialize(Local<Object> target,
53425398 }
53435399 });
53445400 }
5345- Local<FunctionTemplate> db_tmpl = NewFunctionTemplate (isolate, Database::New);
5346- db_tmpl->InstanceTemplate ()->SetInternalFieldCount (
5347- Database::kInternalFieldCount );
53485401 Local<Object> constants = Object::New (isolate);
53495402
53505403 DefineConstants (constants);
53515404
5352- SetProtoMethod (isolate, db_tmpl, " open" , Database::Open);
5353- SetProtoMethod (isolate, db_tmpl, " close" , Database::Close);
5354- SetProtoDispose (isolate, db_tmpl, Database::Dispose);
5355- SetProtoMethod (isolate, db_tmpl, " prepare" , Database::Prepare);
5356- SetProtoMethod (isolate, db_tmpl, " exec" , Database::Exec);
5357- SetProtoMethod (isolate, db_tmpl, " function" , Database::CustomFunction);
5358- SetProtoMethod (isolate, db_tmpl, " createTagStore" , Database::CreateTagStore);
5359- SetProtoMethodNoSideEffect (isolate, db_tmpl, " location" , Database::Location);
5360- SetProtoMethod (isolate, db_tmpl, " aggregate" , Database::AggregateFunction);
5361- SetProtoMethod (isolate, db_tmpl, " createSession" , Database::CreateSession);
5362- SetProtoMethod (isolate, db_tmpl, " applyChangeset" , Database::ApplyChangeset);
5363- SetProtoMethod (
5364- isolate, db_tmpl, " enableLoadExtension" , Database::EnableLoadExtension);
5365- SetProtoMethod (
5366- isolate, db_tmpl, " enableDefensive" , Database::EnableDefensive);
5367- SetProtoMethod (isolate, db_tmpl, " loadExtension" , Database::LoadExtension);
5368- SetProtoMethod (isolate, db_tmpl, " serialize" , Database::Serialize);
5369- SetProtoMethod (isolate, db_tmpl, " deserialize" , Database::Deserialize);
5370- SetProtoMethod (isolate, db_tmpl, " setAuthorizer" , Database::SetAuthorizer);
5371- SetProtoMethod (isolate, db_tmpl, " createModule" , Database::CreateModule);
5372- SetSideEffectFreeGetter (isolate,
5373- db_tmpl,
5374- FIXED_ONE_BYTE_STRING (isolate, " isOpen" ),
5375- Database::IsOpenGetter);
5376- SetSideEffectFreeGetter (isolate,
5377- db_tmpl,
5378- FIXED_ONE_BYTE_STRING (isolate, " isTransaction" ),
5379- Database::IsTransactionGetter);
5380- SetSideEffectFreeGetter (
5381- isolate, db_tmpl, env->limits_string (), Database::LimitsGetter);
5382- Local<String> sqlite_type_key = FIXED_ONE_BYTE_STRING (isolate, " sqlite-type" );
5383- Local<v8::Symbol> sqlite_type_symbol =
5384- v8::Symbol::For (isolate, sqlite_type_key);
5385- Local<String> database_sync_string =
5386- FIXED_ONE_BYTE_STRING (isolate, " node:sqlite" );
5387- db_tmpl->InstanceTemplate ()->Set (sqlite_type_symbol, database_sync_string);
5388-
5389- SetConstructorFunction (context, target, " Database" , db_tmpl);
5405+ SetConstructorFunction (
5406+ context, target, " Database" , Database::GetConstructorTemplate (env));
53905407 SetConstructorFunction (context,
53915408 target,
53925409 " Statement" ,
0 commit comments