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
commitb6ab18a990ffd0daa55665e3153bfed9db547fa7 (patch)
tree5c140c712b897ee3d38be192164c81c2acbdb04a
parent8aa9a26236aa424e99f2c146f7ba3c5c9dcf0b19 (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 13b922d4375..af97b5b4213 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"
@@ -639,6 +640,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;
@@ -662,6 +669,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;
@@ -1705,6 +1718,8 @@ TParserGet(TParser *prs)
{
const TParserStateActionItem *item = NULL;
+ CHECK_FOR_INTERRUPTS();
+
Assert(prs->state);
if (prs->state->posbyte >= prs->lenstr)