Skip to content

Commit 6b445c0

Browse files
committed
Catch possible stack overflow when preparing and compiling user statements
1 parent c75b160 commit 6b445c0

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

src/dsql/dsql.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "../common/intlobj_new.h"
4444
#include "../jrd/jrd.h"
4545
#include "../jrd/status.h"
46+
#include "../jrd/ibsetjmp.h"
4647
#include "../common/CharSet.h"
4748
#include "../dsql/Parser.h"
4849
#include "../dsql/ddl_proto.h"
@@ -85,6 +86,7 @@ using namespace Firebird;
8586
static ULONG get_request_info(thread_db*, DsqlRequest*, ULONG, UCHAR*);
8687
static dsql_dbb* init(Jrd::thread_db*, Jrd::Attachment*);
8788
static DsqlRequest* prepareRequest(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, unsigned, bool);
89+
static DsqlRequest* safePrepareRequest(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, bool);
8890
static RefPtr<DsqlStatement> prepareStatement(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT,
8991
unsigned, bool, ntrace_result_t* traceResult);
9092
static UCHAR* put_item(UCHAR, const USHORT, const UCHAR*, UCHAR*, const UCHAR* const);
@@ -260,7 +262,7 @@ DsqlRequest* DSQL_prepare(thread_db* tdbb,
260262
{
261263
// Allocate a new request block and then prepare the request.
262264

263-
dsqlRequest = prepareRequest(tdbb, database, transaction, length, string, dialect,
265+
dsqlRequest = safePrepareRequest(tdbb, database, transaction, length, string, dialect,
264266
prepareFlags, isInternalRequest);
265267

266268
// Can not prepare a CREATE DATABASE/SCHEMA statement
@@ -335,7 +337,7 @@ void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tr
335337

336338
try
337339
{
338-
dsqlRequest = prepareRequest(tdbb, database, *tra_handle, length, string, dialect,
340+
dsqlRequest = safePrepareRequest(tdbb, database, *tra_handle, length, string, dialect,
339341
0, isInternalRequest);
340342

341343
const auto dsqlStatement = dsqlRequest->getDsqlStatement();
@@ -439,6 +441,23 @@ static dsql_dbb* init(thread_db* tdbb, Jrd::Attachment* attachment)
439441
return attachment->att_dsql_instance;
440442
}
441443

444+
// Use SEH frame when preparing user requests to catch possible stack overflows
445+
static DsqlRequest* safePrepareRequest(thread_db* tdbb, dsql_dbb* database, jrd_tra* transaction,
446+
ULONG textLength, const TEXT* text, USHORT clientDialect, bool isInternalRequest)
447+
{
448+
if (isInternalRequest)
449+
return prepareRequest(tdbb, database, transaction, textLength, text, clientDialect, true);
450+
451+
#ifdef WIN_NT
452+
START_CHECK_FOR_EXCEPTIONS(NULL);
453+
#endif
454+
return prepareRequest(tdbb, database, transaction, textLength, text, clientDialect, false);
455+
456+
#ifdef WIN_NT
457+
END_CHECK_FOR_EXCEPTIONS(NULL);
458+
#endif
459+
}
460+
442461

443462
// Prepare a request for execution.
444463
// Note: caller is responsible for pool handling.

0 commit comments

Comments
 (0)