@@ -126,13 +126,15 @@ inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, int errcode) {
126
126
const char * errstr = sqlite3_errstr (errcode);
127
127
128
128
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
+ }
136
138
}
137
139
138
140
UserDefinedFunction::UserDefinedFunction (Environment* env,
@@ -734,12 +736,14 @@ void DatabaseSync::CreateSession(const FunctionCallbackInfo<Value>& args) {
734
736
}
735
737
}
736
738
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
+
740
741
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
+ }
743
747
if (db_value->IsString ()) {
744
748
String::Utf8Value str (env->isolate (), db_value);
745
749
db_name = std::string (*str);
@@ -808,8 +812,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
808
812
}
809
813
810
814
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
+ }
813
821
814
822
if (!conflictValue->IsUndefined ()) {
815
823
if (!conflictValue->IsFunction ()) {
@@ -837,8 +845,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
837
845
838
846
if (options->HasOwnProperty (env->context (), env->filter_string ())
839
847
.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
+ }
842
854
843
855
if (!filterValue->IsFunction ()) {
844
856
THROW_ERR_INVALID_ARG_TYPE (
@@ -850,6 +862,10 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
850
862
Local<Function> filterFunc = filterValue.As <Function>();
851
863
852
864
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.
853
869
Local<Value> argv[] = {String::NewFromUtf8 (env->isolate (),
854
870
item.c_str (),
855
871
NewStringType::kNormal )
@@ -1214,11 +1230,18 @@ void StatementSync::IterateReturnCallback(
1214
1230
1215
1231
auto self = args.This ();
1216
1232
// 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
+ }
1219
1238
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);
1222
1245
auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1223
1246
if (!stmt->IsFinalized ()) {
1224
1247
sqlite3_reset (stmt->statement_ );
@@ -1242,28 +1265,38 @@ void StatementSync::IterateNextCallback(
1242
1265
1243
1266
auto self = args.This ();
1244
1267
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
+
1245
1274
// 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);
1248
1276
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));
1254
1280
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 ));
1256
1282
args.GetReturnValue ().Set (result);
1257
1283
return ;
1258
1284
}
1259
1285
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);
1262
1292
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 ();
1267
1300
1268
1301
THROW_AND_RETURN_ON_BAD_STATE (
1269
1302
env, stmt->IsFinalized (), " statement has been finalized" );
@@ -1275,8 +1308,12 @@ void StatementSync::IterateNextCallback(
1275
1308
1276
1309
// cleanup when no more rows to fetch
1277
1310
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
+ }
1280
1317
1281
1318
LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1282
1319
LocalVector<Value> values (isolate,
@@ -1329,15 +1366,19 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1329
1366
return ;
1330
1367
}
1331
1368
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
+ }
1338
1378
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));
1341
1382
1342
1383
Local<Object> global = context->Global ();
1343
1384
Local<Value> js_iterator;
@@ -1349,32 +1390,41 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1349
1390
.ToLocal (&js_iterator_prototype))
1350
1391
return ;
1351
1392
1352
- DCHECK_EQ (keys.size (), values.size ());
1353
1393
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 ));
1355
1395
1356
1396
auto num_cols_pd = v8::PropertyDescriptor (
1357
1397
v8::Integer::New (isolate, sqlite3_column_count (stmt->statement_ )), false );
1358
1398
num_cols_pd.set_enumerable (false );
1359
1399
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
+ }
1363
1406
1364
1407
auto stmt_pd =
1365
1408
v8::PropertyDescriptor (v8::External::New (isolate, stmt), false );
1366
1409
stmt_pd.set_enumerable (false );
1367
1410
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
+ }
1370
1417
1371
1418
auto is_finished_pd =
1372
1419
v8::PropertyDescriptor (v8::Boolean::New (isolate, false ), true );
1373
1420
stmt_pd.set_enumerable (false );
1374
1421
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
+ }
1378
1428
1379
1429
args.GetReturnValue ().Set (iterable_iterator);
1380
1430
}
0 commit comments