@@ -126,13 +126,15 @@ inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, int errcode) {
126126 const char * errstr = sqlite3_errstr (errcode);
127127
128128 Environment* env = Environment::GetCurrent (isolate);
129- auto error = CreateSQLiteError (isolate, errstr).ToLocalChecked ();
130- error
131- ->Set (isolate->GetCurrentContext (),
132- env->errcode_string (),
133- Integer::New (isolate, errcode))
134- .ToChecked ();
135- isolate->ThrowException (error);
129+ Local<Object> error;
130+ if (CreateSQLiteError (isolate, errstr).ToLocal (&error) &&
131+ error
132+ ->Set (isolate->GetCurrentContext (),
133+ env->errcode_string (),
134+ Integer::New (isolate, errcode))
135+ .IsJust ()) {
136+ isolate->ThrowException (error);
137+ }
136138}
137139
138140UserDefinedFunction::UserDefinedFunction (Environment* env,
@@ -734,12 +736,14 @@ void DatabaseSync::CreateSession(const FunctionCallbackInfo<Value>& args) {
734736 }
735737 }
736738
737- Local<String> db_key =
738- String::NewFromUtf8 (env->isolate (), " db" , NewStringType::kNormal )
739- .ToLocalChecked ();
739+ Local<String> db_key = FIXED_ONE_BYTE_STRING (env->isolate (), " db" );
740+
740741 if (options->HasOwnProperty (env->context (), db_key).FromJust ()) {
741- Local<Value> db_value =
742- options->Get (env->context (), db_key).ToLocalChecked ();
742+ Local<Value> db_value;
743+ if (!options->Get (env->context (), db_key).ToLocal (&db_value)) {
744+ // An error will have been scheduled.
745+ return ;
746+ }
743747 if (db_value->IsString ()) {
744748 String::Utf8Value str (env->isolate (), db_value);
745749 db_name = std::string (*str);
@@ -808,8 +812,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
808812 }
809813
810814 Local<Object> options = args[1 ].As <Object>();
811- Local<Value> conflictValue =
812- options->Get (env->context (), env->onconflict_string ()).ToLocalChecked ();
815+ Local<Value> conflictValue;
816+ if (!options->Get (env->context (), env->onconflict_string ())
817+ .ToLocal (&conflictValue)) {
818+ // An error will have been scheduled.
819+ return ;
820+ }
813821
814822 if (!conflictValue->IsUndefined ()) {
815823 if (!conflictValue->IsFunction ()) {
@@ -837,8 +845,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
837845
838846 if (options->HasOwnProperty (env->context (), env->filter_string ())
839847 .FromJust ()) {
840- Local<Value> filterValue =
841- options->Get (env->context (), env->filter_string ()).ToLocalChecked ();
848+ Local<Value> filterValue;
849+ if (!options->Get (env->context (), env->filter_string ())
850+ .ToLocal (&filterValue)) {
851+ // An error will have been scheduled.
852+ return ;
853+ }
842854
843855 if (!filterValue->IsFunction ()) {
844856 THROW_ERR_INVALID_ARG_TYPE (
@@ -850,6 +862,10 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
850862 Local<Function> filterFunc = filterValue.As <Function>();
851863
852864 filterCallback = [env, filterFunc](std::string item) -> bool {
865+ // TODO(@jasnell): The use of ToLocalChecked here means that if
866+ // the filter function throws an error the process will crash.
867+ // The filterCallback should be updated to avoid the check and
868+ // propagate the error correctly.
853869 Local<Value> argv[] = {String::NewFromUtf8 (env->isolate (),
854870 item.c_str (),
855871 NewStringType::kNormal )
@@ -1214,11 +1230,18 @@ void StatementSync::IterateReturnCallback(
12141230
12151231 auto self = args.This ();
12161232 // iterator has fetch all result or break, prevent next func to return result
1217- self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1218- .ToChecked ();
1233+ if (self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1234+ .IsNothing ()) {
1235+ // An error will have been scheduled.
1236+ return ;
1237+ }
12191238
1220- auto external_stmt = Local<External>::Cast (
1221- self->Get (context, env->statement_string ()).ToLocalChecked ());
1239+ Local<Value> val;
1240+ if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1241+ // An error will have been scheduled.
1242+ return ;
1243+ }
1244+ auto external_stmt = Local<External>::Cast (val);
12221245 auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
12231246 if (!stmt->IsFinalized ()) {
12241247 sqlite3_reset (stmt->statement_ );
@@ -1242,28 +1265,38 @@ void StatementSync::IterateNextCallback(
12421265
12431266 auto self = args.This ();
12441267
1268+ Local<Value> val;
1269+ if (!self->Get (context, env->isfinished_string ()).ToLocal (&val)) {
1270+ // An error will have been scheduled.
1271+ return ;
1272+ }
1273+
12451274 // skip iteration if is_finished
1246- auto is_finished = Local<Boolean>::Cast (
1247- self->Get (context, env->isfinished_string ()).ToLocalChecked ());
1275+ auto is_finished = Local<Boolean>::Cast (val);
12481276 if (is_finished->Value ()) {
1249- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1250- LocalVector<Value> values (isolate,
1251- {Boolean::New (isolate, true ), Null (isolate)});
1252-
1253- DCHECK_EQ (keys.size (), values.size ());
1277+ Local<Name> keys[] = {env->done_string (), env->value_string ()};
1278+ Local<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
1279+ static_assert (arraysize (keys) == arraysize (values));
12541280 Local<Object> result = Object::New (
1255- isolate, Null (isolate), keys. data (), values. data (), keys. size ( ));
1281+ isolate, Null (isolate), & keys[ 0 ], & values[ 0 ], arraysize (keys ));
12561282 args.GetReturnValue ().Set (result);
12571283 return ;
12581284 }
12591285
1260- auto external_stmt = Local<External>::Cast (
1261- self->Get (context, env->statement_string ()).ToLocalChecked ());
1286+ if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1287+ // An error will have been scheduled.
1288+ return ;
1289+ }
1290+
1291+ auto external_stmt = Local<External>::Cast (val);
12621292 auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1263- auto num_cols =
1264- Local<Integer>::Cast (
1265- self->Get (context, env->num_cols_string ()).ToLocalChecked ())
1266- ->Value ();
1293+
1294+ if (!self->Get (context, env->num_cols_string ()).ToLocal (&val)) {
1295+ // An error will have been scheduled.
1296+ return ;
1297+ }
1298+
1299+ auto num_cols = Local<Integer>::Cast (val)->Value ();
12671300
12681301 THROW_AND_RETURN_ON_BAD_STATE (
12691302 env, stmt->IsFinalized (), " statement has been finalized" );
@@ -1275,8 +1308,12 @@ void StatementSync::IterateNextCallback(
12751308
12761309 // cleanup when no more rows to fetch
12771310 sqlite3_reset (stmt->statement_ );
1278- self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1279- .ToChecked ();
1311+ if (self->Set (
1312+ context, env->isfinished_string (), Boolean::New (isolate, true ))
1313+ .IsNothing ()) {
1314+ // An error would have been scheduled
1315+ return ;
1316+ }
12801317
12811318 LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
12821319 LocalVector<Value> values (isolate,
@@ -1329,15 +1366,19 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
13291366 return ;
13301367 }
13311368
1332- Local<Function> next_func =
1333- Function::New (context, StatementSync::IterateNextCallback)
1334- .ToLocalChecked ();
1335- Local<Function> return_func =
1336- Function::New (context, StatementSync::IterateReturnCallback)
1337- .ToLocalChecked ();
1369+ Local<Function> next_func;
1370+ Local<Function> return_func;
1371+ if (!Function::New (context, StatementSync::IterateNextCallback)
1372+ .ToLocal (&next_func) ||
1373+ !Function::New (context, StatementSync::IterateReturnCallback)
1374+ .ToLocal (&return_func)) {
1375+ // An error will have been scheduled.
1376+ return ;
1377+ }
13381378
1339- LocalVector<Name> keys (isolate, {env->next_string (), env->return_string ()});
1340- LocalVector<Value> values (isolate, {next_func, return_func});
1379+ Local<Name> keys[] = {env->next_string (), env->return_string ()};
1380+ Local<Value> values[] = {next_func, return_func};
1381+ static_assert (arraysize (keys) == arraysize (values));
13411382
13421383 Local<Object> global = context->Global ();
13431384 Local<Value> js_iterator;
@@ -1349,32 +1390,41 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
13491390 .ToLocal (&js_iterator_prototype))
13501391 return ;
13511392
1352- DCHECK_EQ (keys.size (), values.size ());
13531393 Local<Object> iterable_iterator = Object::New (
1354- isolate, js_iterator_prototype, keys. data (), values. data (), keys. size ( ));
1394+ isolate, js_iterator_prototype, & keys[ 0 ], & values[ 0 ], arraysize (keys ));
13551395
13561396 auto num_cols_pd = v8::PropertyDescriptor (
13571397 v8::Integer::New (isolate, sqlite3_column_count (stmt->statement_ )), false );
13581398 num_cols_pd.set_enumerable (false );
13591399 num_cols_pd.set_configurable (false );
1360- iterable_iterator
1361- ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1362- .ToChecked ();
1400+ if (iterable_iterator
1401+ ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1402+ .IsNothing ()) {
1403+ // An error will have been scheduled.
1404+ return ;
1405+ }
13631406
13641407 auto stmt_pd =
13651408 v8::PropertyDescriptor (v8::External::New (isolate, stmt), false );
13661409 stmt_pd.set_enumerable (false );
13671410 stmt_pd.set_configurable (false );
1368- iterable_iterator->DefineProperty (context, env->statement_string (), stmt_pd)
1369- .ToChecked ();
1411+ if (iterable_iterator
1412+ ->DefineProperty (context, env->statement_string (), stmt_pd)
1413+ .IsNothing ()) {
1414+ // An error will have been scheduled.
1415+ return ;
1416+ }
13701417
13711418 auto is_finished_pd =
13721419 v8::PropertyDescriptor (v8::Boolean::New (isolate, false ), true );
13731420 stmt_pd.set_enumerable (false );
13741421 stmt_pd.set_configurable (false );
1375- iterable_iterator
1376- ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1377- .ToChecked ();
1422+ if (iterable_iterator
1423+ ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1424+ .IsNothing ()) {
1425+ // An error will have been scheduled.
1426+ return ;
1427+ }
13781428
13791429 args.GetReturnValue ().Set (iterable_iterator);
13801430}
0 commit comments