From: Ilya Zakharevich Date: Tue, 11 Aug 1998 18:43:29 +0000 (-0400) Subject: Re: Segmentation fault for /a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=aca2d49724bd7cda96bf319bce3078fc016f28f9;p=p5sagit%2Fp5-mst-13.2.git Re: Segmentation fault for /a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ Message-Id: <199808112243.SAA14243@monk.mps.ohio-state.edu> p4raw-id: //depot/perl@1799 --- diff --git a/regcomp.c b/regcomp.c index 0f883f3..ef651fa 100644 --- a/regcomp.c +++ b/regcomp.c @@ -252,6 +252,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 regnode *scan = *scanp, *next; I32 delta = 0; int is_inf = (flags & SCF_DO_SUBSTR) && (data->flags & SF_IS_INF); + int is_inf_internal = 0; /* The studied chunk is infinite */ I32 is_par = OP(scan) == OPEN ? ARG(scan) : 0; scan_data_t data_fake; @@ -366,7 +367,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 if (max1 < minnext + deltanext) max1 = minnext + deltanext; if (deltanext == I32_MAX) - is_inf = 1; + is_inf = is_inf_internal = 1; scan = next; if (data_fake.flags & (SF_HAS_PAR|SF_IN_PAR)) pars++; @@ -461,7 +462,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 min++; /* Fall through. */ case STAR: - is_inf = 1; + is_inf = is_inf_internal = 1; scan = regnext(scan); if (flags & SCF_DO_SUBSTR) { scan_commit(data); @@ -495,8 +496,10 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 && maxcount <= 10000) /* Complement check for big count */ warner(WARN_UNSAFE, "Strange *+?{} on zero-length expression"); min += minnext * mincount; - is_inf |= (maxcount == REG_INFTY && (minnext + deltanext) > 0 - || deltanext == I32_MAX); + is_inf_internal |= (maxcount == REG_INFTY + && (minnext + deltanext) > 0 + || deltanext == I32_MAX); + is_inf |= is_inf_internal; delta += (minnext + deltanext) * maxcount - minnext * mincount; /* Try powerful optimization CURLYX => CURLYN. */ @@ -637,6 +640,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 } data->longest = &(data->longest_float); } + SvREFCNT_dec(last_str); } if (data && (fl & SF_HAS_EVAL)) data->flags |= SF_HAS_EVAL; @@ -652,7 +656,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 scan_commit(data); data->longest = &(data->longest_float); } - is_inf = 1; + is_inf = is_inf_internal = 1; break; } } @@ -711,7 +715,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 finish: *scanp = scan; - *deltap = is_inf ? I32_MAX : delta; + *deltap = is_inf_internal ? I32_MAX : delta; if (flags & SCF_DO_SUBSTR && is_inf) data->pos_delta = I32_MAX - data->pos_min; if (is_par > U8_MAX) @@ -972,9 +976,10 @@ pregcomp(char *exp, char *xend, PMOP *pm) && (!(data.flags & SF_FL_BEFORE_MEOL) || (PL_regflags & PMf_MULTILINE)))) { if (SvCUR(data.longest_fixed) /* ok to leave SvCUR */ - && data.offset_fixed == data.offset_float_min) - goto remove; /* Like in (a)+. */ - + && data.offset_fixed == data.offset_float_min + && SvCUR(data.longest_fixed) == SvCUR(data.longest_float)) + goto remove_float; /* As in (a)+. */ + r->float_substr = data.longest_float; r->float_min_offset = data.offset_float_min; r->float_max_offset = data.offset_float_max; @@ -986,7 +991,7 @@ pregcomp(char *exp, char *xend, PMOP *pm) SvTAIL_on(r->float_substr); } else { - remove: + remove_float: r->float_substr = Nullsv; SvREFCNT_dec(data.longest_float); longest_float_length = 0; diff --git a/t/op/re_tests b/t/op/re_tests index 798355a..b6f654f 100644 --- a/t/op/re_tests +++ b/t/op/re_tests @@ -484,3 +484,4 @@ b\z a\nb\n n - - b\Z a\nb y - - b\z a\nb y - - (^|x)(c) ca y $2 c +a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz x n - -