Skip to content

Commit cd42dd5

Browse files
committed
Fix core dump with buffer-overrun by too long infinitive. Add checking of using
fixed length arrays to prevent array's overrun. Per report by Hannes Dorbath <light@theendofthetunnel.de> and comments by Tom.
1 parent 0153c4c commit cd42dd5

File tree

1 file changed

+47
-32
lines changed

1 file changed

+47
-32
lines changed

src/backend/tsearch/spell.c

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.9 2008/01/01 19:45:52 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.10 2008/01/16 13:01:03 teodor Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1327,8 +1327,7 @@ addToResult(char **forms, char **cur, char *word)
13271327
if (forms == cur || strcmp(word, *(cur - 1)) != 0)
13281328
{
13291329
*cur = pstrdup(word);
1330-
cur++;
1331-
*cur = NULL;
1330+
*(cur+1) = NULL;
13321331
return 1;
13331332
}
13341333

@@ -1448,6 +1447,7 @@ NormalizeSubWord(IspellDict *Conf, char *word, int flag)
14481447
typedef struct SplitVar
14491448
{
14501449
int nstem;
1450+
int lenstem;
14511451
char **stem;
14521452
struct SplitVar *next;
14531453
} SplitVar;
@@ -1495,21 +1495,38 @@ CopyVar(SplitVar *s, int makedup)
14951495
{
14961496
SplitVar *v = (SplitVar *) palloc(sizeof(SplitVar));
14971497

1498-
v->stem = (char **) palloc(sizeof(char *) * (MAX_NORM));
14991498
v->next = NULL;
15001499
if (s)
15011500
{
15021501
int i;
15031502

1503+
v->lenstem = s->lenstem;
1504+
v->stem = (char **) palloc(sizeof(char *) * v->lenstem);
15041505
v->nstem = s->nstem;
15051506
for (i = 0; i < s->nstem; i++)
15061507
v->stem[i] = (makedup) ? pstrdup(s->stem[i]) : s->stem[i];
15071508
}
15081509
else
1510+
{
1511+
v->lenstem = 16;
1512+
v->stem = (char **) palloc(sizeof(char *) * v->lenstem);
15091513
v->nstem = 0;
1514+
}
15101515
return v;
15111516
}
15121517

1518+
static void
1519+
AddStem(SplitVar *v, char *word)
1520+
{
1521+
if ( v->nstem >= v->lenstem )
1522+
{
1523+
v->lenstem *= 2;
1524+
v->stem = (char **) repalloc(v->stem, sizeof(char *) * v->lenstem);
1525+
}
1526+
1527+
v->stem[v->nstem] = word;
1528+
v->nstem++;
1529+
}
15131530

15141531
static SplitVar *
15151532
SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int wordlen, int startpos, int minpos)
@@ -1550,11 +1567,13 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
15501567
if (level + lenaff - 1 <= minpos)
15511568
continue;
15521569

1570+
if ( lenaff >= MAXNORMLEN )
1571+
continue; /* skip too big value */
15531572
if (lenaff > 0)
15541573
memcpy(buf, word + startpos, lenaff);
15551574
buf[lenaff] = '\0';
15561575

1557-
if (level == FF_COMPOUNDBEGIN)
1576+
if (level == 0)
15581577
compoundflag = FF_COMPOUNDBEGIN;
15591578
else if (level == wordlen - 1)
15601579
compoundflag = FF_COMPOUNDLAST;
@@ -1572,8 +1591,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
15721591

15731592
while (*sptr)
15741593
{
1575-
new->stem[new->nstem] = *sptr;
1576-
new->nstem++;
1594+
AddStem( new, *sptr );
15771595
sptr++;
15781596
}
15791597
pfree(subres);
@@ -1624,8 +1642,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
16241642
if (wordlen == level + 1)
16251643
{
16261644
/* well, it was last word */
1627-
var->stem[var->nstem] = pnstrdup(word + startpos, wordlen - startpos);
1628-
var->nstem++;
1645+
AddStem( var, pnstrdup(word + startpos, wordlen - startpos) );
16291646
pfree(notprobed);
16301647
return var;
16311648
}
@@ -1639,8 +1656,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
16391656
ptr->next = SplitToVariants(Conf, node, var, word, wordlen, startpos, level);
16401657
/* we can find next word */
16411658
level++;
1642-
var->stem[var->nstem] = pnstrdup(word + startpos, level - startpos);
1643-
var->nstem++;
1659+
AddStem( var, pnstrdup(word + startpos, level - startpos) );
16441660
node = Conf->Dictionary;
16451661
startpos = level;
16461662
continue;
@@ -1654,12 +1670,26 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
16541670
level++;
16551671
}
16561672

1657-
var->stem[var->nstem] = pnstrdup(word + startpos, wordlen - startpos);
1658-
var->nstem++;
1673+
AddStem( var, pnstrdup(word + startpos, wordlen - startpos) );
16591674
pfree(notprobed);
16601675
return var;
16611676
}
16621677

1678+
static void
1679+
addNorm( TSLexeme **lres, TSLexeme **lcur, char *word, int flags, uint16 NVariant)
1680+
{
1681+
if ( *lres == NULL )
1682+
*lcur = *lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
1683+
1684+
if ( *lcur - *lres < MAX_NORM-1 ) {
1685+
(*lcur)->lexeme = word;
1686+
(*lcur)->flags = flags;
1687+
(*lcur)->nvariant = NVariant;
1688+
(*lcur)++;
1689+
(*lcur)->lexeme = NULL;
1690+
}
1691+
}
1692+
16631693
TSLexeme *
16641694
NINormalizeWord(IspellDict *Conf, char *word)
16651695
{
@@ -1674,16 +1704,11 @@ NINormalizeWord(IspellDict *Conf, char *word)
16741704
{
16751705
char **ptr = res;
16761706

1677-
lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
1678-
while (*ptr)
1707+
while (*ptr && (lcur-lres) < MAX_NORM)
16791708
{
1680-
lcur->lexeme = *ptr;
1681-
lcur->flags = 0;
1682-
lcur->nvariant = NVariant++;
1683-
lcur++;
1709+
addNorm( &lres, &lcur, *ptr, 0, NVariant++);
16841710
ptr++;
16851711
}
1686-
lcur->lexeme = NULL;
16871712
pfree(res);
16881713
}
16891714

@@ -1704,28 +1729,18 @@ NINormalizeWord(IspellDict *Conf, char *word)
17041729
{
17051730
char **subptr = subres;
17061731

1707-
if (!lcur)
1708-
lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
1709-
17101732
while (*subptr)
17111733
{
17121734
for (i = 0; i < var->nstem - 1; i++)
17131735
{
1714-
lcur->lexeme = (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]);
1715-
lcur->flags = 0;
1716-
lcur->nvariant = NVariant;
1717-
lcur++;
1736+
addNorm( &lres, &lcur, (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]), 0, NVariant);
17181737
}
17191738

1720-
lcur->lexeme = *subptr;
1721-
lcur->flags = 0;
1722-
lcur->nvariant = NVariant;
1723-
lcur++;
1739+
addNorm( &lres, &lcur, *subptr, 0, NVariant);
17241740
subptr++;
17251741
NVariant++;
17261742
}
17271743

1728-
lcur->lexeme = NULL;
17291744
pfree(subres);
17301745
var->stem[0] = NULL;
17311746
pfree(var->stem[var->nstem - 1]);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy