Add missing array-enlargement logic to test_regex.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 17 Jan 2021 17:53:48 +0000 (12:53 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 17 Jan 2021 17:53:48 +0000 (12:53 -0500)
The stanza to report a "partial" match could overrun the initially
allocated output array, so it needs its own copy of the array-resizing
logic that's in the main loop.  I overlooked the need for this in
ca8217c10.

Per report from Alexander Lakhin.

Discussion: https://postgr.es/m/3206aace-50db-e02a-bbea-76d5cdaa2cb6@gmail.com

src/test/modules/test_regex/test_regex.c

index ad3c6d3b1a6c5749d0ab7c0e3080532d0d5b6a4f..095751cf04ee36e254f17d2918e442c4e3a8032d 100644 (file)
@@ -555,6 +555,18 @@ setup_test_matches(text *orig_str,
         */
        if (matchctx->nmatches == 0 && re_flags->partial && re_flags->indices)
        {
+               /* enlarge output space if needed */
+               while (array_idx + matchctx->npatterns * 2 + 1 > array_len)
+               {
+                       array_len += array_len + 1; /* 2^n-1 => 2^(n+1)-1 */
+                       if (array_len > MaxAllocSize / sizeof(int))
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+                                                errmsg("too many regular expression matches")));
+                       matchctx->match_locs = (int *) repalloc(matchctx->match_locs,
+                                                                                                       sizeof(int) * array_len);
+               }
+
                matchctx->match_locs[array_idx++] = matchctx->details.rm_extend.rm_so;
                matchctx->match_locs[array_idx++] = matchctx->details.rm_extend.rm_eo;
                /* we don't have pmatch data, so emit -1 */
@@ -566,6 +578,8 @@ setup_test_matches(text *orig_str,
                matchctx->nmatches++;
        }
 
+       Assert(array_idx <= array_len);
+
        if (eml > 1)
        {
                int64           maxsiz = eml * (int64) maxlen;