@@ -120,13 +120,15 @@ inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, int errcode) {
120120 const char * errstr = sqlite3_errstr (errcode);
121121
122122 Environment* env = Environment::GetCurrent (isolate);
123- auto error = CreateSQLiteError (isolate, errstr).ToLocalChecked ();
124- error
125- ->Set (isolate->GetCurrentContext (),
126- env->errcode_string (),
127- Integer::New (isolate, errcode))
128- .ToChecked ();
129- isolate->ThrowException (error);
123+ Local<Object> error;
124+ if (CreateSQLiteError (isolate, errstr).ToLocal (&error) &&
125+ error
126+ ->Set (isolate->GetCurrentContext (),
127+ env->errcode_string (),
128+ Integer::New (isolate, errcode))
129+ .IsJust ()) {
130+ isolate->ThrowException (error);
131+ }
130132}
131133
132134class UserDefinedFunction {
@@ -755,12 +757,14 @@ void DatabaseSync::CreateSession(const FunctionCallbackInfo<Value>& args) {
755757 }
756758 }
757759
758- Local<String> db_key =
759- String::NewFromUtf8 (env->isolate (), " db" , NewStringType::kNormal )
760- .ToLocalChecked ();
760+ Local<String> db_key = FIXED_ONE_BYTE_STRING (env->isolate (), " db" );
761+
761762 if (options->HasOwnProperty (env->context (), db_key).FromJust ()) {
762- Local<Value> db_value =
763- options->Get (env->context (), db_key).ToLocalChecked ();
763+ Local<Value> db_value;
764+ if (!options->Get (env->context (), db_key).ToLocal (&db_value)) {
765+ // An error will have been scheduled.
766+ return ;
767+ }
764768 if (db_value->IsString ()) {
765769 String::Utf8Value str (env->isolate (), db_value);
766770 db_name = std::string (*str);
@@ -829,8 +833,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
829833 }
830834
831835 Local<Object> options = args[1 ].As <Object>();
832- Local<Value> conflictValue =
833- options->Get (env->context (), env->onconflict_string ()).ToLocalChecked ();
836+ Local<Value> conflictValue;
837+ if (!options->Get (env->context (), env->onconflict_string ())
838+ .ToLocal (&conflictValue)) {
839+ // An error will have been scheduled.
840+ return ;
841+ }
834842
835843 if (!conflictValue->IsUndefined ()) {
836844 if (!conflictValue->IsFunction ()) {
@@ -858,8 +866,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
858866
859867 if (options->HasOwnProperty (env->context (), env->filter_string ())
860868 .FromJust ()) {
861- Local<Value> filterValue =
862- options->Get (env->context (), env->filter_string ()).ToLocalChecked ();
869+ Local<Value> filterValue;
870+ if (!options->Get (env->context (), env->filter_string ())
871+ .ToLocal (&filterValue)) {
872+ // An error will have been scheduled.
873+ return ;
874+ }
863875
864876 if (!filterValue->IsFunction ()) {
865877 THROW_ERR_INVALID_ARG_TYPE (
@@ -871,6 +883,10 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
871883 Local<Function> filterFunc = filterValue.As <Function>();
872884
873885 filterCallback = [env, filterFunc](std::string item) -> bool {
886+ // TODO(@jasnell): The use of ToLocalChecked here means that if
887+ // the filter function throws an error the process will crash.
888+ // The filterCallback should be updated to avoid the check and
889+ // propagate the error correctly.
874890 Local<Value> argv[] = {String::NewFromUtf8 (env->isolate (),
875891 item.c_str (),
876892 NewStringType::kNormal )
@@ -1240,11 +1256,18 @@ void StatementSync::IterateReturnCallback(
12401256
12411257 auto self = args.This ();
12421258 // iterator has fetch all result or break, prevent next func to return result
1243- self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1244- .ToChecked ();
1259+ if (self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1260+ .IsNothing ()) {
1261+ // An error will have been scheduled.
1262+ return ;
1263+ }
12451264
1246- auto external_stmt = Local<External>::Cast (
1247- self->Get (context, env->statement_string ()).ToLocalChecked ());
1265+ Local<Value> val;
1266+ if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1267+ // An error will have been scheduled.
1268+ return ;
1269+ }
1270+ auto external_stmt = Local<External>::Cast (val);
12481271 auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
12491272 if (!stmt->IsFinalized ()) {
12501273 sqlite3_reset (stmt->statement_ );
@@ -1268,28 +1291,38 @@ void StatementSync::IterateNextCallback(
12681291
12691292 auto self = args.This ();
12701293
1294+ Local<Value> val;
1295+ if (!self->Get (context, env->isfinished_string ()).ToLocal (&val)) {
1296+ // An error will have been scheduled.
1297+ return ;
1298+ }
1299+
12711300 // skip iteration if is_finished
1272- auto is_finished = Local<Boolean>::Cast (
1273- self->Get (context, env->isfinished_string ()).ToLocalChecked ());
1301+ auto is_finished = Local<Boolean>::Cast (val);
12741302 if (is_finished->Value ()) {
1275- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1276- LocalVector<Value> values (isolate,
1277- {Boolean::New (isolate, true ), Null (isolate)});
1278-
1279- DCHECK_EQ (keys.size (), values.size ());
1303+ Local<Name> keys[] = {env->done_string (), env->value_string ()};
1304+ Local<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
1305+ static_assert (arraysize (keys) == arraysize (values));
12801306 Local<Object> result = Object::New (
1281- isolate, Null (isolate), keys. data (), values. data (), keys. size ( ));
1307+ isolate, Null (isolate), & keys[ 0 ], & values[ 0 ], arraysize (keys ));
12821308 args.GetReturnValue ().Set (result);
12831309 return ;
12841310 }
12851311
1286- auto external_stmt = Local<External>::Cast (
1287- self->Get (context, env->statement_string ()).ToLocalChecked ());
1312+ if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1313+ // An error will have been scheduled.
1314+ return ;
1315+ }
1316+
1317+ auto external_stmt = Local<External>::Cast (val);
12881318 auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1289- auto num_cols =
1290- Local<Integer>::Cast (
1291- self->Get (context, env->num_cols_string ()).ToLocalChecked ())
1292- ->Value ();
1319+
1320+ if (!self->Get (context, env->num_cols_string ()).ToLocal (&val)) {
1321+ // An error will have been scheduled.
1322+ return ;
1323+ }
1324+
1325+ auto num_cols = Local<Integer>::Cast (val)->Value ();
12931326
12941327 THROW_AND_RETURN_ON_BAD_STATE (
12951328 env, stmt->IsFinalized (), " statement has been finalized" );
@@ -1301,8 +1334,12 @@ void StatementSync::IterateNextCallback(
13011334
13021335 // cleanup when no more rows to fetch
13031336 sqlite3_reset (stmt->statement_ );
1304- self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1305- .ToChecked ();
1337+ if (self->Set (
1338+ context, env->isfinished_string (), Boolean::New (isolate, true ))
1339+ .IsNothing ()) {
1340+ // An error would have been scheduled
1341+ return ;
1342+ }
13061343
13071344 LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
13081345 LocalVector<Value> values (isolate,
@@ -1356,15 +1393,19 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
13561393 return ;
13571394 }
13581395
1359- Local<Function> next_func =
1360- Function::New (context, StatementSync::IterateNextCallback)
1361- .ToLocalChecked ();
1362- Local<Function> return_func =
1363- Function::New (context, StatementSync::IterateReturnCallback)
1364- .ToLocalChecked ();
1396+ Local<Function> next_func;
1397+ Local<Function> return_func;
1398+ if (!Function::New (context, StatementSync::IterateNextCallback)
1399+ .ToLocal (&next_func) ||
1400+ !Function::New (context, StatementSync::IterateReturnCallback)
1401+ .ToLocal (&return_func)) {
1402+ // An error will have been scheduled.
1403+ return ;
1404+ }
13651405
1366- LocalVector<Name> keys (isolate, {env->next_string (), env->return_string ()});
1367- LocalVector<Value> values (isolate, {next_func, return_func});
1406+ Local<Name> keys[] = {env->next_string (), env->return_string ()};
1407+ Local<Value> values[] = {next_func, return_func};
1408+ static_assert (arraysize (keys) == arraysize (values));
13681409
13691410 Local<Object> global = context->Global ();
13701411 Local<Value> js_iterator;
@@ -1376,32 +1417,41 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
13761417 .ToLocal (&js_iterator_prototype))
13771418 return ;
13781419
1379- DCHECK_EQ (keys.size (), values.size ());
13801420 Local<Object> iterable_iterator = Object::New (
1381- isolate, js_iterator_prototype, keys. data (), values. data (), keys. size ( ));
1421+ isolate, js_iterator_prototype, & keys[ 0 ], & values[ 0 ], arraysize (keys ));
13821422
13831423 auto num_cols_pd = v8::PropertyDescriptor (
13841424 v8::Integer::New (isolate, sqlite3_column_count (stmt->statement_ )), false );
13851425 num_cols_pd.set_enumerable (false );
13861426 num_cols_pd.set_configurable (false );
1387- iterable_iterator
1388- ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1389- .ToChecked ();
1427+ if (iterable_iterator
1428+ ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1429+ .IsNothing ()) {
1430+ // An error will have been scheduled.
1431+ return ;
1432+ }
13901433
13911434 auto stmt_pd =
13921435 v8::PropertyDescriptor (v8::External::New (isolate, stmt), false );
13931436 stmt_pd.set_enumerable (false );
13941437 stmt_pd.set_configurable (false );
1395- iterable_iterator->DefineProperty (context, env->statement_string (), stmt_pd)
1396- .ToChecked ();
1438+ if (iterable_iterator
1439+ ->DefineProperty (context, env->statement_string (), stmt_pd)
1440+ .IsNothing ()) {
1441+ // An error will have been scheduled.
1442+ return ;
1443+ }
13971444
13981445 auto is_finished_pd =
13991446 v8::PropertyDescriptor (v8::Boolean::New (isolate, false ), true );
14001447 stmt_pd.set_enumerable (false );
14011448 stmt_pd.set_configurable (false );
1402- iterable_iterator
1403- ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1404- .ToChecked ();
1449+ if (iterable_iterator
1450+ ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1451+ .IsNothing ()) {
1452+ // An error will have been scheduled.
1453+ return ;
1454+ }
14051455
14061456 args.GetReturnValue ().Set (iterable_iterator);
14071457}
0 commit comments