File perl-regexec-heap-overflow.diff of Package perl
--- regexec.c.orig 2017-08-23 20:25:05.000000000 +0000
+++ regexec.c 2024-05-08 13:17:40.592177335 +0000
@@ -1487,7 +1487,9 @@ Perl_re_intuit_start(pTHX_
? trie_utf8_fold \
: trie_latin_utf8_fold)))
-#define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uscan, len, uvc, charid, foldlen, foldbuf, uniflags) \
+/* 'uscan' is set to foldbuf, and incremented, so below the end of uscan is
+ * 'foldbuf+sizeof(foldbuf)' */
+#define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uc_end, uscan, len, uvc, charid, foldlen, foldbuf, uniflags) \
STMT_START { \
STRLEN skiplen; \
U8 flags = FOLD_FLAGS_FULL; \
@@ -1504,7 +1506,7 @@ STMT_START {
case trie_utf8_fold: \
do_trie_utf8_fold: \
if ( foldlen>0 ) { \
- uvc = utf8n_to_uvchr( (const U8*) uscan, UTF8_MAXLEN, &len, uniflags ); \
+ uvc = utf8n_to_uvchr( (const U8*) uscan, foldlen, &len, uniflags ); \
foldlen -= len; \
uscan += len; \
len=0; \
@@ -1522,7 +1524,7 @@ STMT_START {
/* FALLTHROUGH */ \
case trie_latin_utf8_fold: \
if ( foldlen>0 ) { \
- uvc = utf8n_to_uvchr( (const U8*) uscan, UTF8_MAXLEN, &len, uniflags ); \
+ uvc = utf8n_to_uvchr( (const U8*) uscan, foldlen, &len, uniflags ); \
foldlen -= len; \
uscan += len; \
len=0; \
@@ -1541,7 +1543,7 @@ STMT_START {
} \
/* FALLTHROUGH */ \
case trie_utf8: \
- uvc = utf8n_to_uvchr( (const U8*) uc, UTF8_MAXLEN, &len, uniflags ); \
+ uvc = utf8n_to_uvchr( (const U8*) uc, uc_end - uc, &len, uniflags ); \
break; \
case trie_plain: \
uvc = (UV)*uc; \
@@ -2624,7 +2626,7 @@ S_find_byclass(pTHX_ regexp * prog, cons
points[pointpos++ % maxlen]= uc;
if (foldlen || uc < (U8*)strend) {
REXEC_TRIE_READ_CHAR(trie_type, trie,
- widecharmap, uc,
+ widecharmap, uc, (U8*)strend,
uscan, len, uvc, charid, foldlen,
foldbuf, uniflags);
DEBUG_TRIE_EXECUTE_r({
@@ -5685,7 +5687,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo,
/* read a char and goto next state */
if ( base && (foldlen || uc < (U8*)(reginfo->strend))) {
I32 offset;
- REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc,
+ REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, (U8*)(reginfo->strend),
uscan, len, uvc, charid, foldlen,
foldbuf, uniflags);
charcount++;
@@ -5822,7 +5824,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo,
while (foldlen) {
if (!--chars)
break;
- uvc = utf8n_to_uvchr(uscan, UTF8_MAXLEN, &len,
+ uvc = utf8n_to_uvchr(uscan, foldlen, &len,
uniflags);
uscan += len;
foldlen -= len;