Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f5157a9

Browse files
committed
Defend against stack overrun in a few more places.
SplitToVariants() in the ispell code, lseg_inside_poly() in geo_ops.c, and regex_selectivity_sub() in selectivity estimation could recurse until stack overflow; fix by adding check_stack_depth() calls. So could next() in the regex compiler, but that case is better fixed by converting its tail recursion to a loop. (We probably get better code that way too, since next() can now be inlined into its sole caller.) There remains a reachable stack overrun in the Turkish stemmer, but we'll need some advice from the Snowball people about how to fix that. Per report from Egor Chindyaskin and Alexander Lakhin. These mistakes are old, so back-patch to all supported branches. Richard Guo and Tom Lane Discussion: https://postgr.es/m/[email protected]
1 parent 1a9c3ff commit f5157a9

File tree

4 files changed

+13
-2
lines changed

4 files changed

+13
-2
lines changed

src/backend/regex/regc_lex.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ next(struct vars *v)
278278
{
279279
chr c;
280280

281+
next_restart: /* loop here after eating a comment */
282+
281283
/* errors yield an infinite sequence of failures */
282284
if (ISERR())
283285
return 0; /* the error has set nexttype to EOS */
@@ -595,8 +597,7 @@ next(struct vars *v)
595597
if (!ATEOS())
596598
v->now++;
597599
assert(v->nexttype == v->lasttype);
598-
return next(v);
599-
break;
600+
goto next_restart;
600601
case CHR('='): /* positive lookahead */
601602
NOTE(REG_ULOOKAROUND);
602603
RETV(LACON, LATYPE_AHEAD_POS);

src/backend/tsearch/spell.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "postgres.h"
6464

6565
#include "catalog/pg_collation.h"
66+
#include "miscadmin.h"
6667
#include "tsearch/dicts/spell.h"
6768
#include "tsearch/ts_locale.h"
6869
#include "utils/memutils.h"
@@ -2394,6 +2395,9 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
23942395
char *notprobed;
23952396
int compoundflag = 0;
23962397

2398+
/* since this function recurses, it could be driven to stack overflow */
2399+
check_stack_depth();
2400+
23972401
notprobed = (char *) palloc(wordlen);
23982402
memset(notprobed, 1, wordlen);
23992403
var = CopyVar(orig, 1);

src/backend/utils/adt/geo_ops.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,6 +3862,9 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
38623862
bool res = true,
38633863
intersection = false;
38643864

3865+
/* since this function recurses, it could be driven to stack overflow */
3866+
check_stack_depth();
3867+
38653868
t.p[0] = *a;
38663869
t.p[1] = *b;
38673870
s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];

src/backend/utils/adt/selfuncs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6022,6 +6022,9 @@ regex_selectivity_sub(const char *patt, int pattlen, bool case_insensitive)
60226022
int paren_pos = 0; /* dummy init to keep compiler quiet */
60236023
int pos;
60246024

6025+
/* since this function recurses, it could be driven to stack overflow */
6026+
check_stack_depth();
6027+
60256028
for (pos = 0; pos < pattlen; pos++)
60266029
{
60276030
if (patt[pos] == '(')

0 commit comments

Comments
 (0)