提交 cd42dd5a 编写于 作者: T Teodor Sigaev

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.
上级 0153c4c4
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.9 2008/01/01 19:45:52 momjian Exp $ * $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.10 2008/01/16 13:01:03 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1327,8 +1327,7 @@ addToResult(char **forms, char **cur, char *word) ...@@ -1327,8 +1327,7 @@ addToResult(char **forms, char **cur, char *word)
if (forms == cur || strcmp(word, *(cur - 1)) != 0) if (forms == cur || strcmp(word, *(cur - 1)) != 0)
{ {
*cur = pstrdup(word); *cur = pstrdup(word);
cur++; *(cur+1) = NULL;
*cur = NULL;
return 1; return 1;
} }
...@@ -1448,6 +1447,7 @@ NormalizeSubWord(IspellDict *Conf, char *word, int flag) ...@@ -1448,6 +1447,7 @@ NormalizeSubWord(IspellDict *Conf, char *word, int flag)
typedef struct SplitVar typedef struct SplitVar
{ {
int nstem; int nstem;
int lenstem;
char **stem; char **stem;
struct SplitVar *next; struct SplitVar *next;
} SplitVar; } SplitVar;
...@@ -1495,21 +1495,38 @@ CopyVar(SplitVar *s, int makedup) ...@@ -1495,21 +1495,38 @@ CopyVar(SplitVar *s, int makedup)
{ {
SplitVar *v = (SplitVar *) palloc(sizeof(SplitVar)); SplitVar *v = (SplitVar *) palloc(sizeof(SplitVar));
v->stem = (char **) palloc(sizeof(char *) * (MAX_NORM));
v->next = NULL; v->next = NULL;
if (s) if (s)
{ {
int i; int i;
v->lenstem = s->lenstem;
v->stem = (char **) palloc(sizeof(char *) * v->lenstem);
v->nstem = s->nstem; v->nstem = s->nstem;
for (i = 0; i < s->nstem; i++) for (i = 0; i < s->nstem; i++)
v->stem[i] = (makedup) ? pstrdup(s->stem[i]) : s->stem[i]; v->stem[i] = (makedup) ? pstrdup(s->stem[i]) : s->stem[i];
} }
else else
{
v->lenstem = 16;
v->stem = (char **) palloc(sizeof(char *) * v->lenstem);
v->nstem = 0; v->nstem = 0;
}
return v; return v;
} }
static void
AddStem(SplitVar *v, char *word)
{
if ( v->nstem >= v->lenstem )
{
v->lenstem *= 2;
v->stem = (char **) repalloc(v->stem, sizeof(char *) * v->lenstem);
}
v->stem[v->nstem] = word;
v->nstem++;
}
static SplitVar * static SplitVar *
SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int wordlen, int startpos, int minpos) 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 ...@@ -1550,11 +1567,13 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
if (level + lenaff - 1 <= minpos) if (level + lenaff - 1 <= minpos)
continue; continue;
if ( lenaff >= MAXNORMLEN )
continue; /* skip too big value */
if (lenaff > 0) if (lenaff > 0)
memcpy(buf, word + startpos, lenaff); memcpy(buf, word + startpos, lenaff);
buf[lenaff] = '\0'; buf[lenaff] = '\0';
if (level == FF_COMPOUNDBEGIN) if (level == 0)
compoundflag = FF_COMPOUNDBEGIN; compoundflag = FF_COMPOUNDBEGIN;
else if (level == wordlen - 1) else if (level == wordlen - 1)
compoundflag = FF_COMPOUNDLAST; compoundflag = FF_COMPOUNDLAST;
...@@ -1572,8 +1591,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int ...@@ -1572,8 +1591,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
while (*sptr) while (*sptr)
{ {
new->stem[new->nstem] = *sptr; AddStem( new, *sptr );
new->nstem++;
sptr++; sptr++;
} }
pfree(subres); pfree(subres);
...@@ -1624,8 +1642,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int ...@@ -1624,8 +1642,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
if (wordlen == level + 1) if (wordlen == level + 1)
{ {
/* well, it was last word */ /* well, it was last word */
var->stem[var->nstem] = pnstrdup(word + startpos, wordlen - startpos); AddStem( var, pnstrdup(word + startpos, wordlen - startpos) );
var->nstem++;
pfree(notprobed); pfree(notprobed);
return var; return var;
} }
...@@ -1639,8 +1656,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int ...@@ -1639,8 +1656,7 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
ptr->next = SplitToVariants(Conf, node, var, word, wordlen, startpos, level); ptr->next = SplitToVariants(Conf, node, var, word, wordlen, startpos, level);
/* we can find next word */ /* we can find next word */
level++; level++;
var->stem[var->nstem] = pnstrdup(word + startpos, level - startpos); AddStem( var, pnstrdup(word + startpos, level - startpos) );
var->nstem++;
node = Conf->Dictionary; node = Conf->Dictionary;
startpos = level; startpos = level;
continue; continue;
...@@ -1654,12 +1670,26 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int ...@@ -1654,12 +1670,26 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
level++; level++;
} }
var->stem[var->nstem] = pnstrdup(word + startpos, wordlen - startpos); AddStem( var, pnstrdup(word + startpos, wordlen - startpos) );
var->nstem++;
pfree(notprobed); pfree(notprobed);
return var; return var;
} }
static void
addNorm( TSLexeme **lres, TSLexeme **lcur, char *word, int flags, uint16 NVariant)
{
if ( *lres == NULL )
*lcur = *lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
if ( *lcur - *lres < MAX_NORM-1 ) {
(*lcur)->lexeme = word;
(*lcur)->flags = flags;
(*lcur)->nvariant = NVariant;
(*lcur)++;
(*lcur)->lexeme = NULL;
}
}
TSLexeme * TSLexeme *
NINormalizeWord(IspellDict *Conf, char *word) NINormalizeWord(IspellDict *Conf, char *word)
{ {
...@@ -1674,16 +1704,11 @@ NINormalizeWord(IspellDict *Conf, char *word) ...@@ -1674,16 +1704,11 @@ NINormalizeWord(IspellDict *Conf, char *word)
{ {
char **ptr = res; char **ptr = res;
lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme)); while (*ptr && (lcur-lres) < MAX_NORM)
while (*ptr)
{ {
lcur->lexeme = *ptr; addNorm( &lres, &lcur, *ptr, 0, NVariant++);
lcur->flags = 0;
lcur->nvariant = NVariant++;
lcur++;
ptr++; ptr++;
} }
lcur->lexeme = NULL;
pfree(res); pfree(res);
} }
...@@ -1704,28 +1729,18 @@ NINormalizeWord(IspellDict *Conf, char *word) ...@@ -1704,28 +1729,18 @@ NINormalizeWord(IspellDict *Conf, char *word)
{ {
char **subptr = subres; char **subptr = subres;
if (!lcur)
lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
while (*subptr) while (*subptr)
{ {
for (i = 0; i < var->nstem - 1; i++) for (i = 0; i < var->nstem - 1; i++)
{ {
lcur->lexeme = (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]); addNorm( &lres, &lcur, (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]), 0, NVariant);
lcur->flags = 0;
lcur->nvariant = NVariant;
lcur++;
} }
lcur->lexeme = *subptr; addNorm( &lres, &lcur, *subptr, 0, NVariant);
lcur->flags = 0;
lcur->nvariant = NVariant;
lcur++;
subptr++; subptr++;
NVariant++; NVariant++;
} }
lcur->lexeme = NULL;
pfree(subres); pfree(subres);
var->stem[0] = NULL; var->stem[0] = NULL;
pfree(var->stem[var->nstem - 1]); pfree(var->stem[var->nstem - 1]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册