text *input = PG_GETARG_TEXT_PP(0);
char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
UnicodeNormalizationForm form;
- int size;
+ size_t size;
char32_t *input_chars;
char32_t *output_chars;
unsigned char *p;
text *result;
- int i;
+ size_t i;
form = unicode_norm_form_from_string(formstr);
/* convert to char32_t */
size = pg_mbstrlen_with_len(VARDATA_ANY(input), VARSIZE_ANY_EXHDR(input));
- input_chars = palloc((size + 1) * sizeof(char32_t));
+ input_chars = palloc_array(char32_t, size + 1);
p = (unsigned char *) VARDATA_ANY(input);
for (i = 0; i < size; i++)
{
text *input = PG_GETARG_TEXT_PP(0);
char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
UnicodeNormalizationForm form;
- int size;
+ size_t size;
char32_t *input_chars;
char32_t *output_chars;
unsigned char *p;
- int i;
+ size_t i;
UnicodeNormalizationQC quickcheck;
- int output_size;
+ size_t output_size;
bool result;
form = unicode_norm_form_from_string(formstr);
/* convert to char32_t */
size = pg_mbstrlen_with_len(VARDATA_ANY(input), VARSIZE_ANY_EXHDR(input));
- input_chars = palloc((size + 1) * sizeof(char32_t));
+ input_chars = palloc_array(char32_t, size + 1);
p = (unsigned char *) VARDATA_ANY(input);
for (i = 0; i < size; i++)
{
#include "common/unicode_norm_hashfunc.h"
#include "common/unicode_normprops_table.h"
#include "port/pg_bswap.h"
+#include "utils/memutils.h"
#else
#include "common/unicode_norm_table.h"
#endif
/*
* Calculate how many characters long the decomposed version will be.
+ *
+ * Some characters decompose to quite a few code points, so that the
+ * decomposed version's size could overrun MaxAllocSize, and even 32-bit
+ * size_t, even though the input string presumably fits in that. In
+ * frontend we want to just return NULL in that case, so monitor the sum
+ * and exit early once we'd need more than MaxAllocSize bytes.
*/
decomp_size = 0;
for (p = input; *p; p++)
+ {
decomp_size += get_decomposed_size(*p, compat);
+ if (unlikely(decomp_size > MaxAllocSize / sizeof(char32_t)))
+ {
+#ifndef FRONTEND
+ /* Exit loop and let palloc() throw error below */
+ break;
+#else
+ /* Just return NULL with no explicit error */
+ return NULL;
+#endif
+ }
+ }
decomp_chars = (char32_t *) ALLOC((decomp_size + 1) * sizeof(char32_t));
if (decomp_chars == NULL)