99
1010#include "catalog/pg_type.h"
1111#include "tsearch/ts_locale.h"
12+ #include "utils/memutils.h"
1213
1314
1415PG_MODULE_MAGIC ;
@@ -188,6 +189,18 @@ generate_trgm(char *str, int slen)
188189char * bword ,
189190* eword ;
190191
192+ /*
193+ * Guard against possible overflow in the palloc requests below. (We
194+ * don't worry about the additive constants, since palloc can detect
195+ * requests that are a little above MaxAllocSize --- we just need to
196+ * prevent integer overflow in the multiplications.)
197+ */
198+ if ((Size ) (slen /2 ) >= (MaxAllocSize / (sizeof (trgm )* 3 ))||
199+ (Size )slen >= (MaxAllocSize /pg_database_encoding_max_length ()))
200+ ereport (ERROR ,
201+ (errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
202+ errmsg ("out of memory" )));
203+
191204trg = (TRGM * )palloc (TRGMHDRSIZE + sizeof (trgm )* (slen /2 + 1 )* 3 );
192205trg -> flag = ARRKEY ;
193206SET_VARSIZE (trg ,TRGMHDRSIZE );
@@ -197,7 +210,8 @@ generate_trgm(char *str, int slen)
197210
198211tptr = GETARR (trg );
199212
200- buf = palloc (sizeof (char )* (slen + 4 ));
213+ /* Allocate a buffer for case-folded, blank-padded words */
214+ buf = (char * )palloc (slen * pg_database_encoding_max_length ()+ 4 );
201215
202216if (LPADDING > 0 )
203217{
@@ -221,6 +235,7 @@ generate_trgm(char *str, int slen)
221235#ifdef IGNORECASE
222236pfree (bword );
223237#endif
238+
224239buf [LPADDING + bytelen ]= ' ' ;
225240buf [LPADDING + bytelen + 1 ]= ' ' ;
226241
@@ -236,7 +251,10 @@ generate_trgm(char *str, int slen)
236251if ((len = tptr - GETARR (trg ))== 0 )
237252return trg ;
238253
239- if (len > 0 )
254+ /*
255+ * Make trigrams unique.
256+ */
257+ if (len > 1 )
240258{
241259qsort ((void * )GETARR (trg ),len ,sizeof (trgm ),comp_trgm );
242260len = unique_array (GETARR (trg ),len );
@@ -419,6 +437,18 @@ generate_wildcard_trgm(const char *str, int slen)
419437bytelen ;
420438const char * eword ;
421439
440+ /*
441+ * Guard against possible overflow in the palloc requests below. (We
442+ * don't worry about the additive constants, since palloc can detect
443+ * requests that are a little above MaxAllocSize --- we just need to
444+ * prevent integer overflow in the multiplications.)
445+ */
446+ if ((Size ) (slen /2 ) >= (MaxAllocSize / (sizeof (trgm )* 3 ))||
447+ (Size )slen >= (MaxAllocSize /pg_database_encoding_max_length ()))
448+ ereport (ERROR ,
449+ (errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
450+ errmsg ("out of memory" )));
451+
422452trg = (TRGM * )palloc (TRGMHDRSIZE + sizeof (trgm )* (slen /2 + 1 )* 3 );
423453trg -> flag = ARRKEY ;
424454SET_VARSIZE (trg ,TRGMHDRSIZE );
@@ -428,6 +458,7 @@ generate_wildcard_trgm(const char *str, int slen)
428458
429459tptr = GETARR (trg );
430460
461+ /* Allocate a buffer for blank-padded, but not yet case-folded, words */
431462buf = palloc (sizeof (char )* (slen + 4 ));
432463
433464/*
@@ -448,6 +479,7 @@ generate_wildcard_trgm(const char *str, int slen)
448479 * count trigrams
449480 */
450481tptr = make_trigrams (tptr ,buf2 ,bytelen ,charlen );
482+
451483#ifdef IGNORECASE
452484pfree (buf2 );
453485#endif
@@ -461,7 +493,7 @@ generate_wildcard_trgm(const char *str, int slen)
461493/*
462494 * Make trigrams unique.
463495 */
464- if (len > 0 )
496+ if (len > 1 )
465497{
466498qsort ((void * )GETARR (trg ),len ,sizeof (trgm ),comp_trgm );
467499len = unique_array (GETARR (trg ),len );