Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)