aboutsummaryrefslogtreecommitdiff
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
commit4c61afa47c618a11ad78b91dcd083e73b6332e82 (patch)
treebf3cf74c2399c6f897df6c42eda14e64de112650
parentc1589923c681877ee06e352922a942ed1d6d9bb9 (diff)
downloadpostgresql-4c61afa47c618a11ad78b91dcd083e73b6332e82.tar.gz
postgresql-4c61afa47c618a11ad78b91dcd083e73b6332e82.zip
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 98029e78fb4..290c2223205 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"
@@ -632,6 +633,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;
@@ -655,6 +662,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;
@@ -1698,6 +1711,8 @@ TParserGet(TParser *prs)
{
const TParserStateActionItem *item = NULL;
+ CHECK_FOR_INTERRUPTS();
+
Assert(prs->state);
if (prs->state->posbyte >= prs->lenstr)