@ -3,9 +3,10 @@
*/
*/
# include "trgm.h"
# include "trgm.h"
# include <ctype.h>
# include <ctype.h>
# include "utils/array.h"
# include "catalog/pg_type.h"
# include "catalog/pg_type.h"
# include "tsearch/ts_locale.h"
# include "tsearch/ts_locale.h"
# include "utils/array.h"
# include "utils/memutils.h"
PG_MODULE_MAGIC ;
PG_MODULE_MAGIC ;
@ -172,6 +173,18 @@ generate_trgm(char *str, int slen)
char * bword ,
char * bword ,
* eword ;
* eword ;
/*
* Guard against possible overflow in the palloc requests below . ( We
* don ' t worry about the additive constants , since palloc can detect
* requests that are a little above MaxAllocSize - - - we just need to
* prevent integer overflow in the multiplications . )
*/
if ( ( Size ) ( slen / 2 ) > = ( MaxAllocSize / ( sizeof ( trgm ) * 3 ) ) | |
( Size ) slen > = ( MaxAllocSize / pg_database_encoding_max_length ( ) ) )
ereport ( ERROR ,
( errcode ( ERRCODE_PROGRAM_LIMIT_EXCEEDED ) ,
errmsg ( " out of memory " ) ) ) ;
trg = ( TRGM * ) palloc ( TRGMHDRSIZE + sizeof ( trgm ) * ( slen / 2 + 1 ) * 3 ) ;
trg = ( TRGM * ) palloc ( TRGMHDRSIZE + sizeof ( trgm ) * ( slen / 2 + 1 ) * 3 ) ;
trg - > flag = ARRKEY ;
trg - > flag = ARRKEY ;
SET_VARSIZE ( trg , TRGMHDRSIZE ) ;
SET_VARSIZE ( trg , TRGMHDRSIZE ) ;
@ -181,7 +194,8 @@ generate_trgm(char *str, int slen)
tptr = GETARR ( trg ) ;
tptr = GETARR ( trg ) ;
buf = palloc ( sizeof ( char ) * ( slen + 4 ) ) ;
/* Allocate a buffer for case-folded, blank-padded words */
buf = ( char * ) palloc ( slen * pg_database_encoding_max_length ( ) + 4 ) ;
if ( LPADDING > 0 )
if ( LPADDING > 0 )
{
{
@ -205,6 +219,7 @@ generate_trgm(char *str, int slen)
# ifdef IGNORECASE
# ifdef IGNORECASE
pfree ( bword ) ;
pfree ( bword ) ;
# endif
# endif
buf [ LPADDING + bytelen ] = ' ' ;
buf [ LPADDING + bytelen ] = ' ' ;
buf [ LPADDING + bytelen + 1 ] = ' ' ;
buf [ LPADDING + bytelen + 1 ] = ' ' ;
@ -220,7 +235,10 @@ generate_trgm(char *str, int slen)
if ( ( len = tptr - GETARR ( trg ) ) = = 0 )
if ( ( len = tptr - GETARR ( trg ) ) = = 0 )
return trg ;
return trg ;
if ( len > 0 )
/*
* Make trigrams unique .
*/
if ( len > 1 )
{
{
qsort ( ( void * ) GETARR ( trg ) , len , sizeof ( trgm ) , comp_trgm ) ;
qsort ( ( void * ) GETARR ( trg ) , len , sizeof ( trgm ) , comp_trgm ) ;
len = unique_array ( GETARR ( trg ) , len ) ;
len = unique_array ( GETARR ( trg ) , len ) ;