summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-06-24 17:18:08 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2023-06-24 17:18:08 -0400
commita77d901714416f6bd4343c367585b060f385bbbc (patch)
treeca6c5176e8d34e1349f50c222b3688c76304c77f
parentf08faee4b94504e30b21ce85bda459f6e5281145 (diff)
Check for interrupts and stack overflow in TParserGet().
TParserGet() recurses for some token types, meaning it's possible to drive it to stack overflow. Since this is a minority behavior, I chose to add the check_stack_depth() call to the two places that recurse rather than doing it during every single call. While at it, add CHECK_FOR_INTERRUPTS(), because this can run unpleasantly long for long inputs. Per bug #17995 from Zuming Jiang. This is old, so back-patch to all supported branches. Discussion: https://postgr.es/m/17995-9f20ff3e6389db4c@postgresql.org
-rw-r--r--src/backend/tsearch/wparser_def.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/backend/tsearch/wparser_def.c b/src/backend/tsearch/wparser_def.c
index eae1f4f7943..916db5a4746 100644
--- a/src/backend/tsearch/wparser_def.c
+++ b/src/backend/tsearch/wparser_def.c
@@ -18,6 +18,7 @@
#include "catalog/pg_collation.h"
#include "commands/defrem.h"
+#include "miscadmin.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_public.h"
#include "tsearch/ts_type.h"
@@ -631,6 +632,12 @@ p_ishost(TParser *prs)
tmpprs->wanthost = true;
+ /*
+ * Check stack depth before recursing. (Since TParserGet() doesn't
+ * normally recurse, we put the cost of checking here not there.)
+ */
+ check_stack_depth();
+
if (TParserGet(tmpprs) && tmpprs->type == HOST)
{
prs->state->posbyte += tmpprs->lenbytetoken;
@@ -654,6 +661,12 @@ p_isURLPath(TParser *prs)
tmpprs->state = newTParserPosition(tmpprs->state);
tmpprs->state->state = TPS_InURLPathFirst;
+ /*
+ * Check stack depth before recursing. (Since TParserGet() doesn't
+ * normally recurse, we put the cost of checking here not there.)
+ */
+ check_stack_depth();
+
if (TParserGet(tmpprs) && tmpprs->type == URLPATH)
{
prs->state->posbyte += tmpprs->lenbytetoken;
@@ -1697,6 +1710,8 @@ TParserGet(TParser *prs)
{
const TParserStateActionItem *item = NULL;
+ CHECK_FOR_INTERRUPTS();
+
Assert(prs->state);
if (prs->state->posbyte >= prs->lenstr)