From 77ebeeba5f5d47be96b3cef485cb98b1c4980510 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Mon, 30 Sep 2013 14:06:23 -0600 Subject: [PATCH] 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.) --- regcomp.c | 11 ++++++----- t/re/re_tests | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) 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 -- 2.7.4