sqlite: fix use-after-free in StatementSync due to premature GC · nodejs/node@8410c95
@@ -535,7 +535,8 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) {
535535 sqlite3_stmt* s = nullptr;
536536int r = sqlite3_prepare_v2(db->connection_, *sql, -1, &s, 0);
537537CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void());
538- BaseObjectPtr<StatementSync> stmt = StatementSync::Create(env, db, s);
538+ BaseObjectPtr<StatementSync> stmt =
539+StatementSync::Create(env, BaseObjectPtr<DatabaseSync>(db), s);
539540 db->statements_.insert(stmt.get());
540541 args.GetReturnValue().Set(stmt->object());
541542}
@@ -946,11 +947,10 @@ void DatabaseSync::LoadExtension(const FunctionCallbackInfo<Value>& args) {
946947947948StatementSync::StatementSync(Environment* env,
948949 Local<Object> object,
949- DatabaseSync* db,
950+BaseObjectPtr<DatabaseSync> db,
950951 sqlite3_stmt* stmt)
951- : BaseObject(env, object) {
952+ : BaseObject(env, object), db_(std::move(db)) {
952953MakeWeak();
953- db_ = db;
954954 statement_ = stmt;
955955// In the future, some of these options could be set at the database
956956// connection level and inherited by statements to reduce boilerplate.
@@ -977,7 +977,7 @@ inline bool StatementSync::IsFinalized() {
977977978978bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
979979int r = sqlite3_clear_bindings(statement_);
980-CHECK_ERROR_OR_THROW(env()->isolate(), db_, r, SQLITE_OK, false);
980+CHECK_ERROR_OR_THROW(env()->isolate(), db_.get(), r, SQLITE_OK, false);
981981982982int anon_idx = 1;
983983int anon_start = 0;
@@ -1107,7 +1107,7 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
11071107return false;
11081108 }
110911091110-CHECK_ERROR_OR_THROW(env()->isolate(), db_, r, SQLITE_OK, false);
1110+CHECK_ERROR_OR_THROW(env()->isolate(), db_.get(), r, SQLITE_OK, false);
11111111return true;
11121112}
11131113@@ -1173,7 +1173,7 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
11731173 env, stmt->IsFinalized(), "statement has been finalized");
11741174 Isolate* isolate = env->isolate();
11751175int r = sqlite3_reset(stmt->statement_);
1176-CHECK_ERROR_OR_THROW(isolate, stmt->db_, r, SQLITE_OK, void());
1176+CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_OK, void());
1177117711781178if (!stmt->BindParams(args)) {
11791179return;
@@ -1202,7 +1202,7 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
12021202 rows.emplace_back(row);
12031203 }
120412041205-CHECK_ERROR_OR_THROW(isolate, stmt->db_, r, SQLITE_DONE, void());
1205+CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_DONE, void());
12061206 args.GetReturnValue().Set(Array::New(isolate, rows.data(), rows.size()));
12071207}
12081208@@ -1270,7 +1270,8 @@ void StatementSync::IterateNextCallback(
1270127012711271int r = sqlite3_step(stmt->statement_);
12721272if (r != SQLITE_ROW) {
1273-CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_, r, SQLITE_DONE, void());
1273+CHECK_ERROR_OR_THROW(
1274+ env->isolate(), stmt->db_.get(), r, SQLITE_DONE, void());
1274127512751276// cleanup when no more rows to fetch
12761277sqlite3_reset(stmt->statement_);
@@ -1322,7 +1323,7 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
13221323auto isolate = env->isolate();
13231324auto context = env->context();
13241325int r = sqlite3_reset(stmt->statement_);
1325-CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_, r, SQLITE_OK, void());
1326+CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void());
1326132713271328if (!stmt->BindParams(args)) {
13281329return;
@@ -1386,7 +1387,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
13861387 env, stmt->IsFinalized(), "statement has been finalized");
13871388 Isolate* isolate = env->isolate();
13881389int r = sqlite3_reset(stmt->statement_);
1389-CHECK_ERROR_OR_THROW(isolate, stmt->db_, r, SQLITE_OK, void());
1390+CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_OK, void());
1390139113911392if (!stmt->BindParams(args)) {
13921393return;
@@ -1396,7 +1397,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
13961397 r = sqlite3_step(stmt->statement_);
13971398if (r == SQLITE_DONE) return;
13981399if (r != SQLITE_ROW) {
1399-THROW_ERR_SQLITE_ERROR(isolate, stmt->db_);
1400+THROW_ERR_SQLITE_ERROR(isolate, stmt->db_.get());
14001401return;
14011402 }
14021403@@ -1432,7 +1433,7 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
14321433THROW_AND_RETURN_ON_BAD_STATE(
14331434 env, stmt->IsFinalized(), "statement has been finalized");
14341435int r = sqlite3_reset(stmt->statement_);
1435-CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_, r, SQLITE_OK, void());
1436+CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void());
1436143714371438if (!stmt->BindParams(args)) {
14381439return;
@@ -1441,7 +1442,7 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
14411442auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });
14421443 r = sqlite3_step(stmt->statement_);
14431444if (r != SQLITE_ROW && r != SQLITE_DONE) {
1444-THROW_ERR_SQLITE_ERROR(env->isolate(), stmt->db_);
1445+THROW_ERR_SQLITE_ERROR(env->isolate(), stmt->db_.get());
14451446return;
14461447 }
14471448@@ -1597,9 +1598,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
15971598return tmpl;
15981599}
159916001600-BaseObjectPtr<StatementSync> StatementSync::Create(Environment* env,
1601- DatabaseSync* db,
1602- sqlite3_stmt* stmt) {
1601+BaseObjectPtr<StatementSync> StatementSync::Create(
1602+ Environment* env, BaseObjectPtr<DatabaseSync> db, sqlite3_stmt* stmt) {
16031603 Local<Object> obj;
16041604if (!GetConstructorTemplate(env)
16051605 ->InstanceTemplate()
@@ -1608,7 +1608,7 @@ BaseObjectPtr<StatementSync> StatementSync::Create(Environment* env,
16081608return BaseObjectPtr<StatementSync>();
16091609 }
161016101611-return MakeBaseObject<StatementSync>(env, obj, db, stmt);
1611+return MakeBaseObject<StatementSync>(env, obj, std::move(db), stmt);
16121612}
1613161316141614Session::Session(Environment* env,
@@ -1675,7 +1675,7 @@ void Session::Changeset(const FunctionCallbackInfo<Value>& args) {
16751675void* pChangeset;
16761676int r = sqliteChangesetFunc(session->session_, &nChangeset, &pChangeset);
16771677CHECK_ERROR_OR_THROW(
1678- env->isolate(), session->database_, r, SQLITE_OK, void());
1678+ env->isolate(), session->database_.get(), r, SQLITE_OK, void());
1679167916801680auto freeChangeset = OnScopeLeave([&] { sqlite3_free(pChangeset); });
16811681