|
43 | 43 | #include "../common/intlobj_new.h"
|
44 | 44 | #include "../jrd/jrd.h"
|
45 | 45 | #include "../jrd/status.h"
|
| 46 | +#include "../jrd/ibsetjmp.h" |
46 | 47 | #include "../common/CharSet.h"
|
47 | 48 | #include "../dsql/Parser.h"
|
48 | 49 | #include "../dsql/ddl_proto.h"
|
@@ -85,6 +86,7 @@ using namespace Firebird;
|
85 | 86 | static ULONG get_request_info(thread_db*, DsqlRequest*, ULONG, UCHAR*);
|
86 | 87 | static dsql_dbb* init(Jrd::thread_db*, Jrd::Attachment*);
|
87 | 88 | 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); |
88 | 90 | static RefPtr<DsqlStatement> prepareStatement(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT,
|
89 | 91 | unsigned, bool, ntrace_result_t* traceResult);
|
90 | 92 | static UCHAR* put_item(UCHAR, const USHORT, const UCHAR*, UCHAR*, const UCHAR* const);
|
@@ -260,7 +262,7 @@ DsqlRequest* DSQL_prepare(thread_db* tdbb,
|
260 | 262 | {
|
261 | 263 | // Allocate a new request block and then prepare the request.
|
262 | 264 |
|
263 |
| - dsqlRequest = prepareRequest(tdbb, database, transaction, length, string, dialect, |
| 265 | + dsqlRequest = safePrepareRequest(tdbb, database, transaction, length, string, dialect, |
264 | 266 | prepareFlags, isInternalRequest);
|
265 | 267 |
|
266 | 268 | // Can not prepare a CREATE DATABASE/SCHEMA statement
|
@@ -335,7 +337,7 @@ void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tr
|
335 | 337 |
|
336 | 338 | try
|
337 | 339 | {
|
338 |
| - dsqlRequest = prepareRequest(tdbb, database, *tra_handle, length, string, dialect, |
| 340 | + dsqlRequest = safePrepareRequest(tdbb, database, *tra_handle, length, string, dialect, |
339 | 341 | 0, isInternalRequest);
|
340 | 342 |
|
341 | 343 | const auto dsqlStatement = dsqlRequest->getDsqlStatement();
|
@@ -439,6 +441,23 @@ static dsql_dbb* init(thread_db* tdbb, Jrd::Attachment* attachment)
|
439 | 441 | return attachment->att_dsql_instance;
|
440 | 442 | }
|
441 | 443 |
|
| 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 | + |
442 | 461 |
|
443 | 462 | // Prepare a request for execution.
|
444 | 463 | // Note: caller is responsible for pool handling.
|
|
0 commit comments