From: Karl Williamson Date: Mon, 30 Sep 2013 20:06:23 +0000 (-0600) Subject: PATCH: [perl #120041] regcomp.c missing parens and broken STCLASS X-Git-Tag: upstream/5.20.0~1622 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=77ebeeba5f5d47be96b3cef485cb98b1c4980510;p=platform%2Fupstream%2Fperl.git PATCH: [perl #120041] regcomp.c missing parens and broken STCLASS This was caused by a problem in commit 43a64b8b430604bd4d76fd256a5babdccaf0ab2b which was masked by problems in commit a0dd42312a1f26356d2fdf49656e45b77c2cefb5. The first commit deleted a line it shouldn't have. I thought that a variable wasn't modified before reaching that line, but it turns out it was because another variable is set to point to its address, and was modified inside a subroutine call. The other two lines deleted in the first commit are ok to have deleted. The second commit masked the problems of the first by omitting some necessary grouping parentheses, which caused things to not work as intended, and we didn't have a good test case in our suite to find this problem. (Thanks to Lukas Mai for spotting the problem and submitting a test case.) --- diff --git a/regcomp.c b/regcomp.c index 18897e5..e876378 100644 --- a/regcomp.c +++ b/regcomp.c @@ -835,7 +835,7 @@ S_ssc_is_anything(pTHX_ const regnode_ssc *ssc) assert(OP(ssc) == ANYOF_SYNTHETIC); - if (! ANYOF_FLAGS(ssc) & ANYOF_EMPTY_STRING) { + if (! (ANYOF_FLAGS(ssc) & ANYOF_EMPTY_STRING)) { return FALSE; } @@ -4167,6 +4167,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, flags &= ~SCF_DO_STCLASS_AND; StructCopy(&this_class, data->start_class, regnode_ssc); flags |= SCF_DO_STCLASS_OR; + ANYOF_FLAGS(data->start_class) |= ANYOF_EMPTY_STRING; } } else { /* Non-zero len */ if (flags & SCF_DO_STCLASS_OR) { @@ -6613,7 +6614,7 @@ reStudy: if ((!(r->anchored_substr || r->anchored_utf8) || r->anchored_offset) && stclass_flag - && ! ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING + && ! (ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING) && !ssc_is_anything(data.start_class)) { const U32 n = add_data(pRExC_state, STR_WITH_LEN("f")); @@ -6687,9 +6688,9 @@ reStudy: r->check_substr = r->check_utf8 = r->anchored_substr = r->anchored_utf8 = r->float_substr = r->float_utf8 = NULL; - if (! ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING - && !ssc_is_anything(data.start_class)) - { + if (! (ANYOF_FLAGS(data.start_class) & ANYOF_EMPTY_STRING) + && ! ssc_is_anything(data.start_class)) + { const U32 n = add_data(pRExC_state, STR_WITH_LEN("f")); ssc_finalize(pRExC_state, data.start_class); diff --git a/t/re/re_tests b/t/re/re_tests index 3c031ff..cf3291d 100644 --- a/t/re/re_tests +++ b/t/re/re_tests @@ -1794,6 +1794,8 @@ A+(*PRUNE)BC(?{}) AAABC y $& AAABC (?:(a(*SKIP)b)){0}(?:(?1)|ac) x n - - # RT #119073: PCRE regression test: {0} => NOTHING optimization (?1)(?:(b)){0} b y $& b +# RT #120041 +^A*\z y $& # Keep these lines at the end of the file # vim: softtabstop=0 noexpandtab