Skip to content

Commit fd05a3c

Browse files
committed
sqlite: check sqlite3_step() and sqlite3_reset() results
Signed-off-by: semimikoh <ejffjeosms@gmail.com>
1 parent 841fc90 commit fd05a3c

1 file changed

Lines changed: 59 additions & 15 deletions

File tree

src/node_sqlite.cc

Lines changed: 59 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)) { \
@@ -2893,9 +2904,17 @@ MaybeLocal<Object> StatementExecutionHelper::Run(Environment* env,
28932904
bool use_big_ints) {
28942905
Isolate* isolate = env->isolate();
28952906
EscapableHandleScope scope(isolate);
2896-
sqlite3_step(stmt);
2897-
int r = sqlite3_reset(stmt);
2898-
CHECK_ERROR_OR_THROW(isolate, db, r, SQLITE_OK, MaybeLocal<Object>());
2907+
bool needs_reset = true;
2908+
auto reset = OnScopeLeave([&]() {
2909+
if (needs_reset) sqlite3_reset(stmt);
2910+
});
2911+
2912+
int step_r = sqlite3_step(stmt);
2913+
if (step_r != SQLITE_DONE && step_r != SQLITE_ROW) {
2914+
THROW_ERR_SQLITE_ERROR(isolate, db);
2915+
return MaybeLocal<Object>();
2916+
}
2917+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Object>());
28992918

29002919
sqlite3_int64 last_insert_rowid = sqlite3_last_insert_rowid(db->Connection());
29012920
sqlite3_int64 changes = sqlite3_changes64(db->Connection());
@@ -2969,18 +2988,25 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
29692988
bool use_big_ints) {
29702989
Isolate* isolate = env->isolate();
29712990
EscapableHandleScope scope(isolate);
2972-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt); });
2991+
bool needs_reset = true;
2992+
auto reset = OnScopeLeave([&]() {
2993+
if (needs_reset) sqlite3_reset(stmt);
2994+
});
29732995

29742996
int r = sqlite3_step(stmt);
2975-
if (r == SQLITE_DONE) return scope.Escape(Undefined(isolate));
2997+
if (r == SQLITE_DONE) {
2998+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Value>());
2999+
return scope.Escape(Undefined(isolate));
3000+
}
29763001
if (r != SQLITE_ROW) {
29773002
THROW_ERR_SQLITE_ERROR(isolate, db);
29783003
return MaybeLocal<Value>();
29793004
}
29803005

29813006
int num_cols = sqlite3_column_count(stmt);
29823007
if (num_cols == 0) {
2983-
return Undefined(isolate);
3008+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3009+
return scope.Escape(Undefined(isolate));
29843010
}
29853011

29863012
LocalVector<Value> row_values(isolate);
@@ -2989,9 +3015,9 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
29893015
return MaybeLocal<Value>();
29903016
}
29913017

3018+
Local<Value> result;
29923019
if (return_arrays) {
2993-
return scope.Escape(
2994-
Array::New(isolate, row_values.data(), row_values.size()));
3020+
result = Array::New(isolate, row_values.data(), row_values.size());
29953021
} else {
29963022
LocalVector<Name> keys(isolate);
29973023
keys.reserve(num_cols);
@@ -3004,9 +3030,12 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
30043030
}
30053031

30063032
DCHECK_EQ(keys.size(), row_values.size());
3007-
return scope.Escape(Object::New(
3008-
isolate, Null(isolate), keys.data(), row_values.data(), num_cols));
3033+
result = Object::New(
3034+
isolate, Null(isolate), keys.data(), row_values.data(), num_cols);
30093035
}
3036+
3037+
RESET_AND_CHECK(isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3038+
return scope.Escape(result);
30103039
}
30113040

30123041
void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
@@ -3023,15 +3052,19 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
30233052
return;
30243053
}
30253054

3026-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });
3027-
3055+
bool needs_reset = true;
3056+
auto reset = OnScopeLeave([&]() {
3057+
if (needs_reset) sqlite3_reset(stmt->statement_);
3058+
});
30283059
Local<Value> result;
30293060
if (StatementExecutionHelper::All(env,
30303061
stmt->db_.get(),
30313062
stmt->statement_,
30323063
stmt->return_arrays_,
30333064
stmt->use_big_ints_)
30343065
.ToLocal(&result)) {
3066+
RESET_AND_CHECK(isolate, stmt->db_.get(), stmt->statement_, needs_reset,
3067+
void());
30353068
args.GetReturnValue().Set(result);
30363069
}
30373070
}
@@ -3470,14 +3503,19 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
34703503
}
34713504
}
34723505

3473-
auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); });
3506+
bool needs_reset = true;
3507+
auto reset = OnScopeLeave([&]() {
3508+
if (needs_reset) sqlite3_reset(stmt->statement_);
3509+
});
34743510
Local<Value> result;
34753511
if (StatementExecutionHelper::All(env,
34763512
stmt->db_.get(),
34773513
stmt->statement_,
34783514
stmt->return_arrays_,
34793515
stmt->use_big_ints_)
34803516
.ToLocal(&result)) {
3517+
RESET_AND_CHECK(isolate, stmt->db_.get(), stmt->statement_, needs_reset,
3518+
void());
34813519
args.GetReturnValue().Set(result);
34823520
}
34833521
}
@@ -3702,7 +3740,10 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
37023740
if (r != SQLITE_ROW) {
37033741
CHECK_ERROR_OR_THROW(
37043742
env->isolate(), iter->stmt_->db_.get(), r, SQLITE_DONE, void());
3705-
sqlite3_reset(iter->stmt_->statement_);
3743+
RESET_OR_THROW(env->isolate(),
3744+
iter->stmt_->db_.get(),
3745+
iter->stmt_->statement_,
3746+
void());
37063747
MaybeLocal<Value> values[] = {Boolean::New(isolate, true), Null(isolate)};
37073748
Local<Object> result;
37083749
if (NewDictionaryInstanceNullProto(env->context(), iter_template, values)
@@ -3754,7 +3795,10 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
37543795
env, iter->stmt_->IsFinalized(), "statement has been finalized");
37553796
Isolate* isolate = env->isolate();
37563797

3757-
sqlite3_reset(iter->stmt_->statement_);
3798+
RESET_OR_THROW(isolate,
3799+
iter->stmt_->db_.get(),
3800+
iter->stmt_->statement_,
3801+
void());
37583802
iter->done_ = true;
37593803

37603804
auto iter_template = getLazyIterTemplate(env);

0 commit comments

Comments
 (0)