summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--t/re/pat.t10
-rw-r--r--toke.c38
2 files changed, 33 insertions, 15 deletions
diff --git a/t/re/pat.t b/t/re/pat.t
index edb78ca19e..7ee66bf840 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -20,7 +20,7 @@ BEGIN {
require './test.pl';
}
-plan tests => 672; # Update this when adding/deleting tests.
+plan tests => 674; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1399,6 +1399,14 @@ EOP
$s = 'abcd$%#&';
$s =~ s/[a#$b%]/X/gx;
is ($s, 'XXcdXXX&', 'RT #119125 with /x');
+
+ $s = 'abYcd$Y#Y&';
+ my $c = 'Y';
+ $s =~ s/[#$b]$c/X/gx;
+ is ($s, 'aXcdXX&', 'RT #119125 with /x and trailing var');
+
+ ok("a#b" =~ /a[#]
+ b(?{})/x, 'RT #119125 with newline and codeblock');
}
} # End of sub run_tests
diff --git a/toke.c b/toke.c
index fc53c7978e..533f67f7d2 100644
--- a/toke.c
+++ b/toke.c
@@ -3178,22 +3178,32 @@ S_scan_const(pTHX_ char *start)
/* likewise skip #-initiated comments in //x patterns */
else if (*s == '#' && PL_lex_inpat &&
- ((PMOP*)PL_lex_inpat)->op_pmflags & RXf_PMf_EXTENDED) {
- while (s+1 < send && *s != '\n') {
+ ((PMOP*)PL_lex_inpat)->op_pmflags & RXf_PMf_EXTENDED)
+ {
+ if (in_charclass) {
/* for maint-5.18, half-fix #-in-charclass bug:
- * *do* recognise codeblocks: /[#](?{})/
- * *don't* recognise interpolated vars: /[#$x]/
- */
- if (in_charclass && !PL_lex_casemods && s+3 < send &&
- s[0] == '(' &&
- s[1] == '?' &&
- ( s[2] == '{'
- || (s[2] == '?' && s[3] == '{')))
- break;
- *d++ = NATIVE_TO_NEED(has_utf8,*s++);
+ * strictly speaking, #-in-charclass has no special
+ * meaning; however, for backwards compatibility,
+ * ignore $variables etc for the rest of the charclass
+ * scope */
+ while (in_charclass && s+1 < send && *s != '\n') {
+ if (*s == ']') {
+ char *s1 = s-1;
+ int esc = 0;
+ while (s1 >= start && *s1-- == '\\')
+ esc = !esc;
+ if (!esc)
+ in_charclass = FALSE;
+ }
+ *d++ = *s++;
+ }
+ continue;
+ }
+ else {
+ /* normal /...#.../x; skipt to end of line */
+ while (s+1 < send && *s != '\n')
+ *d++ = *s++;
}
- if (s+ 1 < send && *s != '\n')
- break; /* we stopped on (?{}), not EOL */
}
/* no further processing of single-quoted regex */