Skip to content

Commit 2fae197

Browse files
committed
sqlite: check sqlite3_step() and sqlite3_reset() results
Signed-off-by: semimikoh <ejffjeosms@gmail.com>
1 parent 9caf674 commit 2fae197

1 file changed

Lines changed: 57 additions & 15 deletions

File tree

‎src/node_sqlite.cc‎

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ inline MaybeLocal<String> Utf8StringMaybeOneByte(Isolate* isolate,
8888
} \
8989
} while (0)
9090

91+
#define RESET_OR_THROW(isolate, db, stmt, ret) \
92+
CHECK_ERROR_OR_THROW((isolate), (db), sqlite3_reset((stmt)), SQLITE_OK, (ret))
93+
94+
// Surface deferred SQLite errors that sqlite3_reset() returns from the prior
95+
// sqlite3_step(). Disables the safety-net reset guard via |needs_reset|.
96+
#define RESET_AND_CHECK(isolate, db, stmt, needs_reset, ret) \
97+
do { \
98+
(needs_reset) = false; \
99+
RESET_OR_THROW((isolate), (db), (stmt), (ret)); \
100+
} while (0)
101+
91102
#define THROW_AND_RETURN_ON_BAD_STATE(env, condition, msg) \
92103
do { \
93104
if ((condition)) { \
@@ -2989,9 +3000,17 @@ MaybeLocal<Object> StatementExecutionHelper::Run(Environment* env,
29893000
bool use_big_ints) {
29903001
Isolate* isolate = env->isolate();
29913002
EscapableHandleScope scope(isolate);
2992-
sqlite3_step(stmt);
2993-
int r = sqlite3_reset(stmt);
2994-
CHECK_ERROR_OR_THROW(isolate, db, r, SQLITE_OK, MaybeLocal<Object>());
3003+
bool needs_reset = true;
3004+
auto reset = OnScopeLeave([&]() {
3005+
if (needs_reset) sqlite3_reset(stmt);
3006+
});
3007+
3008+
int step_r = sqlite3_step(stmt);
3009+
if (step_r != SQLITE_DONE && step_r != SQLITE_ROW) {
3010+
THROW_ERR_SQLITE_ERROR(isolate, db);
3011+
return MaybeLocal<Object>();
3012+
}
3013+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Object>());
29953014

29963015
sqlite3_int64 last_insert_rowid = sqlite3_last_insert_rowid(db->Connection());
29973016
sqlite3_int64 changes = sqlite3_changes64(db->Connection());
@@ -3065,18 +3084,25 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
30653084
bool use_big_ints) {
30663085
Isolate* isolate = env->isolate();
30673086
EscapableHandleScope scope(isolate);
3068-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt); });
3087+
bool needs_reset = true;
3088+
auto reset = OnScopeLeave([&]() {
3089+
if (needs_reset) sqlite3_reset(stmt);
3090+
});
30693091

30703092
int r = sqlite3_step(stmt);
3071-
if (r == SQLITE_DONE) return scope.Escape(Undefined(isolate));
3093+
if (r == SQLITE_DONE) {
3094+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3095+
return scope.Escape(Undefined(isolate));
3096+
}
30723097
if (r != SQLITE_ROW) {
30733098
THROW_ERR_SQLITE_ERROR(isolate, db);
30743099
return MaybeLocal<Value>();
30753100
}
30763101

30773102
int num_cols = sqlite3_column_count(stmt);
30783103
if (num_cols == 0) {
3079-
return Undefined(isolate);
3104+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3105+
return scope.Escape(Undefined(isolate));
30803106
}
30813107

30823108
LocalVector<Value> row_values(isolate);
@@ -3085,9 +3111,9 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
30853111
return MaybeLocal<Value>();
30863112
}
30873113

3114+
Local<Value> result;
30883115
if (return_arrays) {
3089-
return scope.Escape(
3090-
Array::New(isolate, row_values.data(), row_values.size()));
3116+
result = Array::New(isolate, row_values.data(), row_values.size());
30913117
} else {
30923118
LocalVector<Name> keys(isolate);
30933119
keys.reserve(num_cols);
@@ -3100,9 +3126,12 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
31003126
}
31013127

31023128
DCHECK_EQ(keys.size(), row_values.size());
3103-
return scope.Escape(Object::New(
3104-
isolate, Null(isolate), keys.data(), row_values.data(), num_cols));
3129+
result = Object::New(
3130+
isolate, Null(isolate), keys.data(), row_values.data(), num_cols);
31053131
}
3132+
3133+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3134+
return scope.Escape(result);
31063135
}
31073136

31083137
void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
@@ -3119,15 +3148,19 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
31193148
return;
31203149
}
31213150

3122-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });
3123-
3151+
bool needs_reset = true;
3152+
auto reset = OnScopeLeave([&]() {
3153+
if (needs_reset) sqlite3_reset(stmt->statement_);
3154+
});
31243155
Local<Value> result;
31253156
if (StatementExecutionHelper::All(env,
31263157
stmt->db_.get(),
31273158
stmt->statement_,
31283159
stmt->return_arrays_,
31293160
stmt->use_big_ints_)
31303161
.ToLocal(&result)) {
3162+
RESET_AND_CHECK(
3163+
isolate, stmt->db_.get(), stmt->statement_, needs_reset, void());
31313164
args.GetReturnValue().Set(result);
31323165
}
31333166
}
@@ -3566,14 +3599,19 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
35663599
}
35673600
}
35683601

3569-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });
3602+
bool needs_reset = true;
3603+
auto reset = OnScopeLeave([&]() {
3604+
if (needs_reset) sqlite3_reset(stmt->statement_);
3605+
});
35703606
Local<Value> result;
35713607
if (StatementExecutionHelper::All(env,
35723608
stmt->db_.get(),
35733609
stmt->statement_,
35743610
stmt->return_arrays_,
35753611
stmt->use_big_ints_)
35763612
.ToLocal(&result)) {
3613+
RESET_AND_CHECK(
3614+
isolate, stmt->db_.get(), stmt->statement_, needs_reset, void());
35773615
args.GetReturnValue().Set(result);
35783616
}
35793617
}
@@ -3800,7 +3838,10 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
38003838
if (r != SQLITE_ROW) {
38013839
CHECK_ERROR_OR_THROW(
38023840
env->isolate(), iter->stmt_->db_.get(), r, SQLITE_DONE, void());
3803-
sqlite3_reset(iter->stmt_->statement_);
3841+
RESET_OR_THROW(env->isolate(),
3842+
iter->stmt_->db_.get(),
3843+
iter->stmt_->statement_,
3844+
void());
38043845
iter->done_ = true;
38053846
MaybeLocal<Value> values[] = {Boolean::New(isolate, true), Null(isolate)};
38063847
Local<Object> result;
@@ -3853,7 +3894,8 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
38533894
env, iter->stmt_->IsFinalized(), "statement has been finalized");
38543895
Isolate* isolate = env->isolate();
38553896

3856-
sqlite3_reset(iter->stmt_->statement_);
3897+
RESET_OR_THROW(
3898+
isolate, iter->stmt_->db_.get(), iter->stmt_->statement_, void());
38573899
iter->done_ = true;
38583900

38593901
auto iter_template = getLazyIterTemplate(env);

0 commit comments

Comments
 (0)