From 47ad3b976ccb0be50fb27b3edde5f4c241819abe Mon Sep 17 00:00:00 2001 From: Hugo van der Sanden Date: Sun, 4 Aug 2019 14:31:29 +0100 Subject: [PATCH 1/3] Include data->pos_delta in #if'd-out diagnostic --- regcomp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/regcomp.c b/regcomp.c index 640c99dfc1a6..2c256cfb0b0a 100644 --- a/regcomp.c +++ b/regcomp.c @@ -5838,9 +5838,10 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, #if 0 Perl_re_printf( aTHX_ "counted=%" UVuf " deltanext=%" UVuf " OPTIMIZE_INFTY=%" UVuf " minnext=%" UVuf - " maxcount=%" UVuf " mincount=%" UVuf "\n", + " maxcount=%" UVuf " mincount=%" UVuf + " data->pos_delta=%" UVuf "\n", (UV)counted, (UV)deltanext, (UV)OPTIMIZE_INFTY, (UV)minnext, (UV)maxcount, - (UV)mincount); + (UV)mincount, (UV)data->pos_delta); if (deltanext != OPTIMIZE_INFTY) Perl_re_printf( aTHX_ "LHS=%" UVuf " RHS=%" UVuf "\n", (UV)(-counted * deltanext + (minnext + deltanext) * maxcount From 2b3938b6f098d6ae55e76767f0dc31963b12139a Mon Sep 17 00:00:00 2001 From: Hugo van der Sanden Date: Sun, 4 Aug 2019 14:07:22 +0100 Subject: [PATCH 2/3] avoid overflow on min_subtract in study_chunk delta and pos_delta may hold OPTIMIZE_INFTY (SSize_t_MAX) to represent infinity; Fixes: #17847 --- regcomp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/regcomp.c b/regcomp.c index 2c256cfb0b0a..e607dd388ff4 100644 --- a/regcomp.c +++ b/regcomp.c @@ -5404,13 +5404,21 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, } min += charlen - min_subtract; assert (min >= 0); - delta += min_subtract; + if (OPTIMIZE_INFTY > min_subtract && delta < OPTIMIZE_INFTY - (SSize_t)min_subtract) { + delta += min_subtract; + } else { + delta = OPTIMIZE_INFTY; + } if (flags & SCF_DO_SUBSTR) { data->pos_min += charlen - min_subtract; if (data->pos_min < 0) { data->pos_min = 0; } - data->pos_delta += min_subtract; + if (OPTIMIZE_INFTY > min_subtract && data->pos_delta < OPTIMIZE_INFTY - (SSize_t)min_subtract ) { + data->pos_delta += min_subtract; + } else { + data->pos_delta = OPTIMIZE_INFTY; + } if (min_subtract) { data->cur_is_floating = 1; /* float */ } From c67a1850d2b751065133fa1a406c24a393c00366 Mon Sep 17 00:00:00 2001 From: Hugo van der Sanden Date: Thu, 8 Aug 2019 17:27:14 +0100 Subject: [PATCH 3/3] data->pos_delta should stick at infinity The expression we're about to add to data->pos_delta in this part of study_chunk() can be both positive or negative; however while we apply an overflow check to avoid exceeding OPTIMIZE_INFTY (used to represent infinity), we'll happily subtract from it when the expression is negative, making it no longer infinite. Fixes: #17847 --- regcomp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/regcomp.c b/regcomp.c index e607dd388ff4..300dd9acc91d 100644 --- a/regcomp.c +++ b/regcomp.c @@ -5856,6 +5856,7 @@ Perl_re_printf( aTHX_ "LHS=%" UVuf " RHS=%" UVuf "\n", - minnext * mincount), (UV)(OPTIMIZE_INFTY - data->pos_delta)); #endif if (deltanext == OPTIMIZE_INFTY + || data->pos_delta == OPTIMIZE_INFTY || -counted * deltanext + (minnext + deltanext) * maxcount - minnext * mincount >= OPTIMIZE_INFTY - data->pos_delta) data->pos_delta = OPTIMIZE_INFTY; else