Skip to content

Commit 689df1b

Browse files
committed
Fix crash of to_tsvector() function on huge input: compareWORD()
function didn't return correct result for word position greate than limit. Per report from Stuart Bishop <stuart@stuartbishop.net>
1 parent 10e1b9d commit 689df1b

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

src/backend/tsearch/to_tsany.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/tsearch/to_tsany.c,v 1.3 2007/09/10 12:36:40 teodor Exp $
10+
* $PostgreSQL: pgsql/src/backend/tsearch/to_tsany.c,v 1.4 2007/09/26 10:09:57 teodor Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -40,7 +40,12 @@ compareWORD(const void *a, const void *b)
4040
((ParsedWord *) b)->len);
4141

4242
if (res == 0)
43+
{
44+
if ( ((ParsedWord *) a)->pos.pos == ((ParsedWord *) b)->pos.pos )
45+
return 0;
46+
4347
return (((ParsedWord *) a)->pos.pos > ((ParsedWord *) b)->pos.pos) ? 1 : -1;
48+
}
4449
return res;
4550
}
4651
return (((ParsedWord *) a)->len > ((ParsedWord *) b)->len) ? 1 : -1;
@@ -66,18 +71,31 @@ uniqueWORD(ParsedWord * a, int4 l)
6671
res = a;
6772
ptr = a + 1;
6873

74+
/*
75+
* Sort words with its positions
76+
*/
6977
qsort((void *) a, l, sizeof(ParsedWord), compareWORD);
78+
79+
/*
80+
* Initialize first word and its first position
81+
*/
7082
tmppos = LIMITPOS(a->pos.pos);
7183
a->alen = 2;
7284
a->pos.apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
7385
a->pos.apos[0] = 1;
7486
a->pos.apos[1] = tmppos;
7587

88+
/*
89+
* Summarize position information for each word
90+
*/
7691
while (ptr - a < l)
7792
{
7893
if (!(ptr->len == res->len &&
7994
strncmp(ptr->word, res->word, res->len) == 0))
8095
{
96+
/*
97+
* Got a new word, so put it in result
98+
*/
8199
res++;
82100
res->len = ptr->len;
83101
res->word = ptr->word;
@@ -89,8 +107,14 @@ uniqueWORD(ParsedWord * a, int4 l)
89107
}
90108
else
91109
{
110+
/*
111+
* The word already exists, so adjust position information.
112+
* But before we should check size of position's array,
113+
* max allowed value for position and uniqueness of position
114+
*/
92115
pfree(ptr->word);
93-
if (res->pos.apos[0] < MAXNUMPOS - 1 && res->pos.apos[res->pos.apos[0]] != MAXENTRYPOS - 1)
116+
if (res->pos.apos[0] < MAXNUMPOS - 1 && res->pos.apos[res->pos.apos[0]] != MAXENTRYPOS - 1 &&
117+
res->pos.apos[res->pos.apos[0]] != LIMITPOS(ptr->pos.pos))
94118
{
95119
if (res->pos.apos[0] + 1 >= res->alen)
96120
{

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