@@ -119,13 +119,15 @@ inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, int errcode) {
119
119
const char * errstr = sqlite3_errstr (errcode);
120
120
121
121
Environment* env = Environment::GetCurrent (isolate);
122
- auto error = CreateSQLiteError (isolate, errstr).ToLocalChecked ();
123
- error
124
- ->Set (isolate->GetCurrentContext (),
125
- env->errcode_string (),
126
- Integer::New (isolate, errcode))
127
- .ToChecked ();
128
- isolate->ThrowException (error);
122
+ Local<Object> error;
123
+ if (CreateSQLiteError (isolate, errstr).ToLocal (&error) &&
124
+ error
125
+ ->Set (isolate->GetCurrentContext (),
126
+ env->errcode_string (),
127
+ Integer::New (isolate, errcode))
128
+ .IsJust ()) {
129
+ isolate->ThrowException (error);
130
+ }
129
131
}
130
132
131
133
class UserDefinedFunction {
@@ -709,12 +711,14 @@ void DatabaseSync::CreateSession(const FunctionCallbackInfo<Value>& args) {
709
711
}
710
712
}
711
713
712
- Local<String> db_key =
713
- String::NewFromUtf8 (env->isolate (), " db" , NewStringType::kNormal )
714
- .ToLocalChecked ();
714
+ Local<String> db_key = FIXED_ONE_BYTE_STRING (env->isolate (), " db" );
715
+
715
716
if (options->HasOwnProperty (env->context (), db_key).FromJust ()) {
716
- Local<Value> db_value =
717
- options->Get (env->context (), db_key).ToLocalChecked ();
717
+ Local<Value> db_value;
718
+ if (!options->Get (env->context (), db_key).ToLocal (&db_value)) {
719
+ // An error will have been scheduled.
720
+ return ;
721
+ }
718
722
if (db_value->IsString ()) {
719
723
String::Utf8Value str (env->isolate (), db_value);
720
724
db_name = std::string (*str);
@@ -783,8 +787,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
783
787
}
784
788
785
789
Local<Object> options = args[1 ].As <Object>();
786
- Local<Value> conflictValue =
787
- options->Get (env->context (), env->onconflict_string ()).ToLocalChecked ();
790
+ Local<Value> conflictValue;
791
+ if (!options->Get (env->context (), env->onconflict_string ())
792
+ .ToLocal (&conflictValue)) {
793
+ // An error will have been scheduled.
794
+ return ;
795
+ }
788
796
789
797
if (!conflictValue->IsUndefined ()) {
790
798
if (!conflictValue->IsFunction ()) {
@@ -812,8 +820,12 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
812
820
813
821
if (options->HasOwnProperty (env->context (), env->filter_string ())
814
822
.FromJust ()) {
815
- Local<Value> filterValue =
816
- options->Get (env->context (), env->filter_string ()).ToLocalChecked ();
823
+ Local<Value> filterValue;
824
+ if (!options->Get (env->context (), env->filter_string ())
825
+ .ToLocal (&filterValue)) {
826
+ // An error will have been scheduled.
827
+ return ;
828
+ }
817
829
818
830
if (!filterValue->IsFunction ()) {
819
831
THROW_ERR_INVALID_ARG_TYPE (
@@ -825,6 +837,10 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
825
837
Local<Function> filterFunc = filterValue.As <Function>();
826
838
827
839
filterCallback = [env, filterFunc](std::string item) -> bool {
840
+ // TODO(@jasnell): The use of ToLocalChecked here means that if
841
+ // the filter function throws an error the process will crash.
842
+ // The filterCallback should be updated to avoid the check and
843
+ // propagate the error correctly.
828
844
Local<Value> argv[] = {String::NewFromUtf8 (env->isolate (),
829
845
item.c_str (),
830
846
NewStringType::kNormal )
@@ -1194,11 +1210,18 @@ void StatementSync::IterateReturnCallback(
1194
1210
1195
1211
auto self = args.This ();
1196
1212
// iterator has fetch all result or break, prevent next func to return result
1197
- self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1198
- .ToChecked ();
1213
+ if (self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1214
+ .IsNothing ()) {
1215
+ // An error will have been scheduled.
1216
+ return ;
1217
+ }
1199
1218
1200
- auto external_stmt = Local<External>::Cast (
1201
- self->Get (context, env->statement_string ()).ToLocalChecked ());
1219
+ Local<Value> val;
1220
+ if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1221
+ // An error will have been scheduled.
1222
+ return ;
1223
+ }
1224
+ auto external_stmt = Local<External>::Cast (val);
1202
1225
auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1203
1226
if (!stmt->IsFinalized ()) {
1204
1227
sqlite3_reset (stmt->statement_ );
@@ -1222,28 +1245,38 @@ void StatementSync::IterateNextCallback(
1222
1245
1223
1246
auto self = args.This ();
1224
1247
1248
+ Local<Value> val;
1249
+ if (!self->Get (context, env->isfinished_string ()).ToLocal (&val)) {
1250
+ // An error will have been scheduled.
1251
+ return ;
1252
+ }
1253
+
1225
1254
// skip iteration if is_finished
1226
- auto is_finished = Local<Boolean>::Cast (
1227
- self->Get (context, env->isfinished_string ()).ToLocalChecked ());
1255
+ auto is_finished = Local<Boolean>::Cast (val);
1228
1256
if (is_finished->Value ()) {
1229
- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1230
- LocalVector<Value> values (isolate,
1231
- {Boolean::New (isolate, true ), Null (isolate)});
1232
-
1233
- DCHECK_EQ (keys.size (), values.size ());
1257
+ Local<Name> keys[] = {env->done_string (), env->value_string ()};
1258
+ Local<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
1259
+ static_assert (arraysize (keys) == arraysize (values));
1234
1260
Local<Object> result = Object::New (
1235
- isolate, Null (isolate), keys. data (), values. data (), keys. size ( ));
1261
+ isolate, Null (isolate), & keys[ 0 ], & values[ 0 ], arraysize (keys ));
1236
1262
args.GetReturnValue ().Set (result);
1237
1263
return ;
1238
1264
}
1239
1265
1240
- auto external_stmt = Local<External>::Cast (
1241
- self->Get (context, env->statement_string ()).ToLocalChecked ());
1266
+ if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1267
+ // An error will have been scheduled.
1268
+ return ;
1269
+ }
1270
+
1271
+ auto external_stmt = Local<External>::Cast (val);
1242
1272
auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1243
- auto num_cols =
1244
- Local<Integer>::Cast (
1245
- self->Get (context, env->num_cols_string ()).ToLocalChecked ())
1246
- ->Value ();
1273
+
1274
+ if (!self->Get (context, env->num_cols_string ()).ToLocal (&val)) {
1275
+ // An error will have been scheduled.
1276
+ return ;
1277
+ }
1278
+
1279
+ auto num_cols = Local<Integer>::Cast (val)->Value ();
1247
1280
1248
1281
THROW_AND_RETURN_ON_BAD_STATE (
1249
1282
env, stmt->IsFinalized (), " statement has been finalized" );
@@ -1255,8 +1288,12 @@ void StatementSync::IterateNextCallback(
1255
1288
1256
1289
// cleanup when no more rows to fetch
1257
1290
sqlite3_reset (stmt->statement_ );
1258
- self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1259
- .ToChecked ();
1291
+ if (self->Set (
1292
+ context, env->isfinished_string (), Boolean::New (isolate, true ))
1293
+ .IsNothing ()) {
1294
+ // An error would have been scheduled
1295
+ return ;
1296
+ }
1260
1297
1261
1298
LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1262
1299
LocalVector<Value> values (isolate,
@@ -1310,15 +1347,19 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1310
1347
return ;
1311
1348
}
1312
1349
1313
- Local<Function> next_func =
1314
- Function::New (context, StatementSync::IterateNextCallback)
1315
- .ToLocalChecked ();
1316
- Local<Function> return_func =
1317
- Function::New (context, StatementSync::IterateReturnCallback)
1318
- .ToLocalChecked ();
1350
+ Local<Function> next_func;
1351
+ Local<Function> return_func;
1352
+ if (!Function::New (context, StatementSync::IterateNextCallback)
1353
+ .ToLocal (&next_func) ||
1354
+ !Function::New (context, StatementSync::IterateReturnCallback)
1355
+ .ToLocal (&return_func)) {
1356
+ // An error will have been scheduled.
1357
+ return ;
1358
+ }
1319
1359
1320
- LocalVector<Name> keys (isolate, {env->next_string (), env->return_string ()});
1321
- LocalVector<Value> values (isolate, {next_func, return_func});
1360
+ Local<Name> keys[] = {env->next_string (), env->return_string ()};
1361
+ Local<Value> values[] = {next_func, return_func};
1362
+ static_assert (arraysize (keys) == arraysize (values));
1322
1363
1323
1364
Local<Object> global = context->Global ();
1324
1365
Local<Value> js_iterator;
@@ -1332,30 +1373,40 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1332
1373
1333
1374
DCHECK_EQ (keys.size (), values.size ());
1334
1375
Local<Object> iterable_iterator = Object::New (
1335
- isolate, js_iterator_prototype, keys. data (), values. data (), keys. size ( ));
1376
+ isolate, js_iterator_prototype, & keys[ 0 ], & values[ 0 ], arraysize (keys ));
1336
1377
1337
1378
auto num_cols_pd = v8::PropertyDescriptor (
1338
1379
v8::Integer::New (isolate, sqlite3_column_count (stmt->statement_ )), false );
1339
1380
num_cols_pd.set_enumerable (false );
1340
1381
num_cols_pd.set_configurable (false );
1341
- iterable_iterator
1342
- ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1343
- .ToChecked ();
1382
+ if (iterable_iterator
1383
+ ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1384
+ .IsNothing ()) {
1385
+ // An error will have been scheduled.
1386
+ return ;
1387
+ }
1344
1388
1345
1389
auto stmt_pd =
1346
1390
v8::PropertyDescriptor (v8::External::New (isolate, stmt), false );
1347
1391
stmt_pd.set_enumerable (false );
1348
1392
stmt_pd.set_configurable (false );
1349
- iterable_iterator->DefineProperty (context, env->statement_string (), stmt_pd)
1350
- .ToChecked ();
1393
+ if (iterable_iterator
1394
+ ->DefineProperty (context, env->statement_string (), stmt_pd)
1395
+ .IsNothing ()) {
1396
+ // An error will have been scheduled.
1397
+ return ;
1398
+ }
1351
1399
1352
1400
auto is_finished_pd =
1353
1401
v8::PropertyDescriptor (v8::Boolean::New (isolate, false ), true );
1354
1402
stmt_pd.set_enumerable (false );
1355
1403
stmt_pd.set_configurable (false );
1356
- iterable_iterator
1357
- ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1358
- .ToChecked ();
1404
+ if (iterable_iterator
1405
+ ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1406
+ .IsNothing ()) {
1407
+ // An error will have been scheduled.
1408
+ return ;
1409
+ }
1359
1410
1360
1411
args.GetReturnValue ().Set (iterable_iterator);
1361
1412
}
0 commit comments