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)
188189 char * 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+
191204 trg = (TRGM * ) palloc (TRGMHDRSIZE + sizeof (trgm ) * (slen / 2 + 1 ) * 3 );
192205 trg -> flag = ARRKEY ;
193206 SET_VARSIZE (trg , TRGMHDRSIZE );
@@ -197,7 +210,8 @@ generate_trgm(char *str, int slen)
197210
198211 tptr = 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
202216 if (LPADDING > 0 )
203217 {
@@ -221,6 +235,7 @@ generate_trgm(char *str, int slen)
221235#ifdef IGNORECASE
222236 pfree (bword );
223237#endif
238+
224239 buf [LPADDING + bytelen ] = ' ' ;
225240 buf [LPADDING + bytelen + 1 ] = ' ' ;
226241
@@ -236,7 +251,10 @@ generate_trgm(char *str, int slen)
236251 if ((len = tptr - GETARR (trg )) == 0 )
237252 return trg ;
238253
239- if (len > 0 )
254+ /*
255+ * Make trigrams unique.
256+ */
257+ if (len > 1 )
240258 {
241259 qsort ((void * ) GETARR (trg ), len , sizeof (trgm ), comp_trgm );
242260 len = unique_array (GETARR (trg ), len );
@@ -419,6 +437,18 @@ generate_wildcard_trgm(const char *str, int slen)
419437 bytelen ;
420438 const 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+
422452 trg = (TRGM * ) palloc (TRGMHDRSIZE + sizeof (trgm ) * (slen / 2 + 1 ) * 3 );
423453 trg -> flag = ARRKEY ;
424454 SET_VARSIZE (trg , TRGMHDRSIZE );
@@ -428,6 +458,7 @@ generate_wildcard_trgm(const char *str, int slen)
428458
429459 tptr = GETARR (trg );
430460
461+ /* Allocate a buffer for blank-padded, but not yet case-folded, words */
431462 buf = palloc (sizeof (char ) * (slen + 4 ));
432463
433464 /*
@@ -448,6 +479,7 @@ generate_wildcard_trgm(const char *str, int slen)
448479 * count trigrams
449480 */
450481 tptr = make_trigrams (tptr , buf2 , bytelen , charlen );
482+
451483#ifdef IGNORECASE
452484 pfree (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 {
466498 qsort ((void * ) GETARR (trg ), len , sizeof (trgm ), comp_trgm );
467499 len = unique_array (GETARR (trg ), len );
0 commit comments