Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
sqlite: refactor authz error handling
  • Loading branch information
araujogui committed Sep 26, 2025
commit 526216d444ff5dbe18d60a879e200effbbf8f15b
52 changes: 10 additions & 42 deletions src/node_sqlite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -233,28 +233,6 @@ inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, DatabaseSync* db) {
}
}

bool DatabaseSync::HasPendingAuthorizerError() const {
Local<Value> error =
object()->GetInternalField(kPendingAuthorizerError).As<Value>();
return !error.IsEmpty() && !error->IsUndefined();
}

void DatabaseSync::StoreAuthorizerError(Local<Value> error) {
if (!HasPendingAuthorizerError()) {
object()->SetInternalField(kPendingAuthorizerError, error);
}
}

void DatabaseSync::RethrowPendingAuthorizerError() {
if (HasPendingAuthorizerError()) {
Local<Value> error =
object()->GetInternalField(kPendingAuthorizerError).As<Value>();
object()->SetInternalField(kPendingAuthorizerError,
Undefined(env()->isolate()));
env()->isolate()->ThrowException(error);
}
}

inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, const char* message) {
Local<Object> e;
if (CreateSQLiteError(isolate, message).ToLocal(&e)) {
Expand Down Expand Up @@ -1149,14 +1127,6 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) {
sqlite3_stmt* s = nullptr;
int r = sqlite3_prepare_v2(db->connection_, *sql, -1, &s, 0);

if (db->HasPendingAuthorizerError()) {
db->RethrowPendingAuthorizerError();
if (s != nullptr) {
sqlite3_finalize(s);
}
return;
}

CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void());
BaseObjectPtr<StatementSync> stmt =
StatementSync::Create(env, BaseObjectPtr<DatabaseSync>(db), s);
Expand All @@ -1178,10 +1148,6 @@ void DatabaseSync::Exec(const FunctionCallbackInfo<Value>& args) {

Utf8Value sql(env->isolate(), args[0].As<String>());
int r = sqlite3_exec(db->connection_, *sql, nullptr, nullptr, nullptr);
if (db->HasPendingAuthorizerError()) {
db->RethrowPendingAuthorizerError();
return;
}
CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void());
}

Expand Down Expand Up @@ -1957,19 +1923,19 @@ int DatabaseSync::AuthorizerCallback(void* user_data,
js_argv.emplace_back(
NullableSQLiteStringToValue(isolate, param4).ToLocalChecked());

TryCatch try_catch(isolate);
MaybeLocal<Value> retval = callback->Call(
context, Undefined(isolate), js_argv.size(), js_argv.data());

if (try_catch.HasCaught()) {
db->StoreAuthorizerError(try_catch.Exception());
Local<Value> result;

if (!retval.ToLocal(&result)) {
db->SetIgnoreNextSQLiteError(true);
return SQLITE_DENY;
}

Local<String> error_message;
Local<Value> result;
if (!retval.ToLocal(&result) || result->IsUndefined() || result->IsNull() ||
!result->IsInt32()) {

if (!result->IsInt32()) {
if (!String::NewFromUtf8(
isolate,
"Authorizer callback must return an integer authorization code")
Expand All @@ -1978,7 +1944,8 @@ int DatabaseSync::AuthorizerCallback(void* user_data,
}

Local<Value> err = Exception::TypeError(error_message);
db->StoreAuthorizerError(err);
isolate->ThrowException(err);
db->SetIgnoreNextSQLiteError(true);
return SQLITE_DENY;
}

Expand All @@ -1993,7 +1960,8 @@ int DatabaseSync::AuthorizerCallback(void* user_data,
}

Local<Value> err = Exception::RangeError(error_message);
db->StoreAuthorizerError(err);
isolate->ThrowException(err);
db->SetIgnoreNextSQLiteError(true);
return SQLITE_DENY;
}

Expand Down
5 changes: 1 addition & 4 deletions src/node_sqlite.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ class DatabaseSync : public BaseObject {
public:
enum InternalFields {
kAuthorizerCallback = BaseObject::kInternalFieldCount,
kPendingAuthorizerError,
kInternalFieldCount
};

Expand Down Expand Up @@ -172,9 +171,7 @@ class DatabaseSync : public BaseObject {
void SetIgnoreNextSQLiteError(bool ignore);
bool ShouldIgnoreSQLiteError();

bool HasPendingAuthorizerError() const;
void StoreAuthorizerError(v8::Local<v8::Value> error);
void RethrowPendingAuthorizerError();


SET_MEMORY_INFO_NAME(DatabaseSync)
SET_SELF_SIZE(DatabaseSync)
Expand Down
Loading