Skip to content

Commit eb58a7e

Browse files
committed
Merge re_eval jumbo fix branch into blead
This re_eval branch contains around 130 commits that collectively reimplement the /(?{})/ mechanism. See the individual commits and the changes to pod/* for more details, but the main highlights are: =item * Code blocks within patterns are now parsed in the same pass as the surrounding code; in particular it is no longer necessary to have balanced braces: this now works: /(?{ $x='{' })/ This means that this error message is longer generated: Sequence (?{...}) not terminated or not {}-balanced in regex but a new error may be seen: Sequence (?{...}) not terminated with ')' In addition, literal code blocks within run-time patterns are only compiled once, at perl compile-time: for my $p (...) { # this 'FOO' block of code is compiled once, at the same time as # the surrounding 'for' loop /$p{(?{FOO;})/; } =item * Lexical variables are now sane as regards scope, recursion and closure behaviour. In particular, C</A(?{B})C/> behaves (from a closure viewpoint) exactly like C</A/ && do { B } && /C/>, while C<qr/A(?{B})C/> is like C<sub {/A/ && do { B } && /C/}>. So this code now works how you might expect, creating three regexes that match 1,2, and 3: for my $i (0..2) { push @r, qr/^(??{$i})$/; } "1" =~ $r[1]; # matches =item * The C<use re 'eval'> pragma is now strictly only required for code blocks defined at runtime; in particular in the following, the text of the $r pattern is still interpolated into the new pattern and recompiled, but the individual compiled code-blocks within $r are reused rather than being recompiled, and C<use re 'eval'> isn't needed any more: my $r = qr/abc(?{....})def/; /xyz$r/; =item * Flow control operators no longer crash. Each code block runs in a new dynamic scope, so C<next> etc. will not see any enclosing loops and C<caller> will not see any calling subroutines. C<return> returns a value from the code block, not from any enclosing subroutine. =item * Perl normally caches the compilation of run-time patterns, and doesn't recompile if the pattern hasn't changed; but this is now disabled if required for the correct behaviour of closures; for example: my $code = '(??{$x})'; for my $x (1..3) { $x =~ /$code/; # recompile to see fresh value of $x each time } =item * C</msix> and C<(?msix)> etc. flags are now propagated into the return value from C<(??{})>; this now works: "AB" =~ /a(??{'b'})/i; =item * Warnings and errors will appear to come from the surrounding code (or for run-time code blocks, from an eval) rather than from an C<re_eval>: use re 'eval'; $c = '(?{ warn "foo" })'; /$c/; /(?{ warn "foo" })/; formerly gave: foo at (re_eval 1) line 1. foo at (re_eval 2) line 1. and now gives: foo at (eval 1) line 1. foo at /tmp/foo line 2. =item * In the pluggable regex API, the regexp_engine struct has acquired a new field C<op_comp>, which is currently just for perl's internal use, and should be initialised to NULL by other regexp plugin modules.
2 parents 3630f57 + db70367 commit eb58a7e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+3949
-1865
lines changed

MANIFEST

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5393,6 +5393,7 @@ t/re/qr-72922.t Test for bug #72922
53935393
t/re/qr_gc.t See if qr doesn't leak
53945394
t/re/qrstack.t See if qr expands the stack properly
53955395
t/re/qr.t See if qr works
5396+
t/re/recompile.t See if pattern caching/recompilation works
53965397
t/re/reg_60508.t See if bug #60508 is fixed
53975398
t/re/reg_email.t See if regex recursion works by parsing email addresses
53985399
t/re/reg_email_thr.t See if regex recursion works by parsing email addresses in another thread

cop.h

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,12 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
11801180
U8 hasargs = 0 /* used by PUSHSUB */
11811181

11821182
#define PUSH_MULTICALL(the_cv) \
1183+
PUSH_MULTICALL_WITHDEPTH(the_cv, 1);
1184+
1185+
/* Like PUSH_MULTICALL, but allows you to specify the CvDEPTH increment,
1186+
* rather than the default of 1 (this isn't part of the public API) */
1187+
1188+
#define PUSH_MULTICALL_WITHDEPTH(the_cv, depth) \
11831189
STMT_START { \
11841190
CV * const _nOnclAshIngNamE_ = the_cv; \
11851191
CV * const cv = _nOnclAshIngNamE_; \
@@ -1191,7 +1197,8 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
11911197
PUSHSTACKi(PERLSI_SORT); \
11921198
PUSHBLOCK(cx, CXt_SUB|CXp_MULTICALL, PL_stack_sp); \
11931199
PUSHSUB(cx); \
1194-
if (++CvDEPTH(cv) >= 2) { \
1200+
CvDEPTH(cv) += depth; \
1201+
if (CvDEPTH(cv) >= 2) { \
11951202
PERL_STACK_OVERFLOW_CHECK(); \
11961203
Perl_pad_push(aTHX_ padlist, CvDEPTH(cv)); \
11971204
} \
@@ -1209,15 +1216,41 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
12091216

12101217
#define POP_MULTICALL \
12111218
STMT_START { \
1212-
if (! --CvDEPTH(multicall_cv)) \
1213-
LEAVESUB(multicall_cv); \
1219+
if (! ((CvDEPTH(multicall_cv) = cx->blk_sub.olddepth)) ) { \
1220+
LEAVESUB(multicall_cv); \
1221+
} \
12141222
POPBLOCK(cx,PL_curpm); \
12151223
POPSTACK; \
12161224
CATCH_SET(multicall_oldcatch); \
12171225
LEAVE; \
12181226
SPAGAIN; \
12191227
} STMT_END
12201228

1229+
/* Change the CV of an already-pushed MULTICALL CxSUB block.
1230+
* (this isn't part of the public API) */
1231+
1232+
#define CHANGE_MULTICALL_WITHDEPTH(the_cv, depth) \
1233+
STMT_START { \
1234+
CV * const _nOnclAshIngNamE_ = the_cv; \
1235+
CV * const cv = _nOnclAshIngNamE_; \
1236+
AV * const padlist = CvPADLIST(cv); \
1237+
cx = &cxstack[cxstack_ix]; \
1238+
assert(cx->cx_type & CXp_MULTICALL); \
1239+
if (! ((CvDEPTH(multicall_cv) = cx->blk_sub.olddepth)) ) { \
1240+
LEAVESUB(multicall_cv); \
1241+
} \
1242+
cx->cx_type &= ~CXp_HASARGS; \
1243+
PUSHSUB(cx); \
1244+
CvDEPTH(cv) += depth; \
1245+
if (CvDEPTH(cv) >= 2) { \
1246+
PERL_STACK_OVERFLOW_CHECK(); \
1247+
Perl_pad_push(aTHX_ padlist, CvDEPTH(cv)); \
1248+
} \
1249+
SAVECOMPPAD(); \
1250+
PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv)); \
1251+
multicall_cv = cv; \
1252+
multicall_cop = CvSTART(cv); \
1253+
} STMT_END
12211254
/*
12221255
* Local variables:
12231256
* c-indentation-style: bsd

dist/B-Deparse/Deparse.pm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4587,7 +4587,10 @@ sub matchop {
45874587
carp("found ".$kid->name." where regcomp expected");
45884588
} else {
45894589
($re, $quote) = $self->regcomp($kid, 21, $extended);
4590-
my $matchop = $kid->first->first;
4590+
my $matchop = $kid->first;
4591+
if ($matchop->name eq 'regcrest') {
4592+
$matchop = $matchop->first;
4593+
}
45914594
if ($matchop->name =~ /^(?:match|transr?|subst)\z/
45924595
&& $matchop->flags & OPf_SPECIAL) {
45934596
$rhs_bound_to_defsv = 1;

dump.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,15 @@ Perl_do_pmop_dump(pTHX_ I32 level, PerlIO *file, const PMOP *pm)
613613
Perl_dump_indent(aTHX_ level, file, "PMf_REPL = ");
614614
op_dump(pm->op_pmreplrootu.op_pmreplroot);
615615
}
616+
if (pm->op_code_list) {
617+
if (pm->op_pmflags & PMf_CODELIST_PRIVATE) {
618+
Perl_dump_indent(aTHX_ level, file, "CODE_LIST =\n");
619+
do_op_dump(level, file, pm->op_code_list);
620+
}
621+
else
622+
Perl_dump_indent(aTHX_ level, file, "CODE_LIST = 0x%"UVxf"\n",
623+
PTR2UV(pm->op_code_list));
624+
}
616625
if (pm->op_pmflags || (PM_GETRE(pm) && RX_CHECK_SUBSTR(PM_GETRE(pm)))) {
617626
SV * const tmpsv = pm_description(pm);
618627
Perl_dump_indent(aTHX_ level, file, "PMFLAGS = (%s)\n", SvCUR(tmpsv) ? SvPVX_const(tmpsv) + 1 : "");
@@ -630,6 +639,9 @@ const struct flag_to_name pmflags_flags_names[] = {
630639
{PMf_RETAINT, ",RETAINT"},
631640
{PMf_EVAL, ",EVAL"},
632641
{PMf_NONDESTRUCT, ",NONDESTRUCT"},
642+
{PMf_HAS_CV, ",HAS_CV"},
643+
{PMf_CODELIST_PRIVATE, ",CODELIST_PRIVATE"},
644+
{PMf_IS_QR, ",IS_QR"}
633645
};
634646

635647
static SV *
@@ -2040,8 +2052,6 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
20402052
(UV)(r->gofs));
20412053
Perl_dump_indent(aTHX_ level, file, " PRE_PREFIX = %"UVuf"\n",
20422054
(UV)(r->pre_prefix));
2043-
Perl_dump_indent(aTHX_ level, file, " SEEN_EVALS = %"UVuf"\n",
2044-
(UV)(r->seen_evals));
20452055
Perl_dump_indent(aTHX_ level, file, " SUBLEN = %"IVdf"\n",
20462056
(IV)(r->sublen));
20472057
if (r->subbeg)
@@ -2062,6 +2072,8 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
20622072
PTR2UV(r->pprivate));
20632073
Perl_dump_indent(aTHX_ level, file, " OFFS = 0x%"UVxf"\n",
20642074
PTR2UV(r->offs));
2075+
Perl_dump_indent(aTHX_ level, file, " QR_ANONCV = 0x%"UVxf"\n",
2076+
PTR2UV(r->qr_anoncv));
20652077
#ifdef PERL_OLD_COPY_ON_WRITE
20662078
Perl_dump_indent(aTHX_ level, file, " SAVED_COPY = 0x%"UVxf"\n",
20672079
PTR2UV(r->saved_copy));

embed.fnc

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ Apd |void |packlist |NN SV *cat|NN const char *pat|NN const char *patend|NN SV
10241024
s |void |pidgone |Pid_t pid|int status
10251025
#endif
10261026
: Used in perly.y
1027-
p |OP* |pmruntime |NN OP *o|NN OP *expr|bool isreg
1027+
p |OP* |pmruntime |NN OP *o|NN OP *expr|bool isreg|I32 floor
10281028
#if defined(PERL_IN_OP_C)
10291029
s |OP* |pmtrans |NN OP* o|NN OP* expr|NN OP* repl
10301030
#endif
@@ -1056,8 +1056,15 @@ Ap |void |regfree_internal|NN REGEXP *const rx
10561056
#if defined(USE_ITHREADS)
10571057
Ap |void* |regdupe_internal|NN REGEXP * const r|NN CLONE_PARAMS* param
10581058
#endif
1059+
EXp |regexp_engine const *|current_re_engine
10591060
Ap |REGEXP*|pregcomp |NN SV * const pattern|const U32 flags
1060-
Ap |REGEXP*|re_compile |NN SV * const pattern|U32 flags
1061+
p |REGEXP*|re_op_compile |NULLOK SV ** const patternp \
1062+
|int pat_count|NULLOK OP *expr \
1063+
|NN const regexp_engine* eng \
1064+
|NULLOK REGEXP *VOL old_re \
1065+
|NULLOK bool *is_bare_re \
1066+
|U32 rx_flags|U32 pm_flags
1067+
Ap |REGEXP*|re_compile |NN SV * const pattern|U32 orig_rx_flags
10611068
Ap |char* |re_intuit_start|NN REGEXP * const rx|NULLOK SV* sv|NN char* strpos \
10621069
|NN char* strend|const U32 flags \
10631070
|NULLOK re_scream_pos_data *data
@@ -1267,13 +1274,6 @@ Apd |I32 |sv_cmp_locale_flags |NULLOK SV *const sv1 \
12671274
Amd |char* |sv_collxfrm |NN SV *const sv|NN STRLEN *const nxp
12681275
Apd |char* |sv_collxfrm_flags |NN SV *const sv|NN STRLEN *const nxp|I32 const flags
12691276
#endif
1270-
: Frustratingly, because regcomp.c is also compiled as ext/re/re_comp.c,
1271-
: anything it needs has to be exported. So this has to be X. I'd rather it
1272-
: wasn't.
1273-
Xpo |OP* |sv_compile_2op_is_broken|NN SV *sv|NN OP **startop \
1274-
|NN const char *code|NN PAD **padp
1275-
ApD |OP* |sv_compile_2op |NN SV *sv|NN OP **startop \
1276-
|NN const char *code|NN PAD **padp
12771277
Apd |int |getcwd_sv |NN SV* sv
12781278
Apd |void |sv_dec |NULLOK SV *const sv
12791279
Apd |void |sv_dec_nomg |NULLOK SV *const sv
@@ -1859,7 +1859,7 @@ sR |I32 |dopoptoloop |I32 startingblock
18591859
sR |I32 |dopoptosub_at |NN const PERL_CONTEXT* cxstk|I32 startingblock
18601860
sR |I32 |dopoptowhen |I32 startingblock
18611861
s |void |save_lines |NULLOK AV *array|NN SV *sv
1862-
s |bool |doeval |int gimme|NULLOK OP** startop \
1862+
s |bool |doeval |int gimme \
18631863
|NULLOK CV* outside|U32 seq|NULLOK HV* hh
18641864
sR |PerlIO *|check_type_and_open|NN SV *name
18651865
#ifndef PERL_DISABLE_PMC
@@ -1996,8 +1996,8 @@ ERs |I32 |regrepeat |NN const regexp *prog|NN const regnode *p|I32 max|int depth
19961996
ERs |I32 |regtry |NN regmatch_info *reginfo|NN char **startpos
19971997
ERs |bool |reginclass |NULLOK const regexp * const prog|NN const regnode * const n|NN const U8 * const p|NULLOK STRLEN *lenp\
19981998
|bool const do_utf8sv_is_utf8
1999-
Es |CHECKPOINT|regcppush |I32 parenfloor
2000-
Es |char* |regcppop |NN const regexp *rex
1999+
Es |CHECKPOINT|regcppush |NN const regexp *rex|I32 parenfloor
2000+
Es |void |regcppop |NN regexp *rex
20012001
ERsn |U8* |reghop3 |NN U8 *s|I32 off|NN const U8 *lim
20022002
ERsM |SV* |core_regclass_swash|NULLOK const regexp *prog \
20032003
|NN const struct regnode *node|bool doinit \
@@ -2114,7 +2114,8 @@ s |char* |scan_ident |NN char *s|NN const char *send|NN char *dest \
21142114
|STRLEN destlen|I32 ck_uni
21152115
sR |char* |scan_inputsymbol|NN char *start
21162116
sR |char* |scan_pat |NN char *start|I32 type
2117-
sR |char* |scan_str |NN char *start|int keep_quoted|int keep_delims
2117+
sR |char* |scan_str |NN char *start|int keep_quoted \
2118+
|int keep_delims|int re_reparse
21182119
sR |char* |scan_subst |NN char *start
21192120
sR |char* |scan_trans |NN char *start
21202121
s |char* |scan_word |NN char *s|NN char *dest|STRLEN destlen \

embed.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,6 @@
558558
#define sv_clear(a) Perl_sv_clear(aTHX_ a)
559559
#define sv_cmp_flags(a,b,c) Perl_sv_cmp_flags(aTHX_ a,b,c)
560560
#define sv_cmp_locale_flags(a,b,c) Perl_sv_cmp_locale_flags(aTHX_ a,b,c)
561-
#define sv_compile_2op(a,b,c,d) Perl_sv_compile_2op(aTHX_ a,b,c,d)
562561
#define sv_copypv(a,b) Perl_sv_copypv(aTHX_ a,b)
563562
#define sv_dec(a) Perl_sv_dec(aTHX_ a)
564563
#define sv_dec_nomg(a) Perl_sv_dec_nomg(aTHX_ a)
@@ -857,6 +856,7 @@
857856
#if defined(PERL_CORE) || defined(PERL_EXT)
858857
#define _is_utf8__perl_idstart(a) Perl__is_utf8__perl_idstart(aTHX_ a)
859858
#define av_reify(a) Perl_av_reify(aTHX_ a)
859+
#define current_re_engine() Perl_current_re_engine(aTHX)
860860
#define is_utf8_X_L(a) Perl_is_utf8_X_L(aTHX_ a)
861861
#define is_utf8_X_LV(a) Perl_is_utf8_X_LV(aTHX_ a)
862862
#define is_utf8_X_LVT(a) Perl_is_utf8_X_LVT(aTHX_ a)
@@ -972,7 +972,7 @@
972972
#define find_byclass(a,b,c,d,e) S_find_byclass(aTHX_ a,b,c,d,e)
973973
#define reg_check_named_buff_matched(a,b) S_reg_check_named_buff_matched(aTHX_ a,b)
974974
#define regcppop(a) S_regcppop(aTHX_ a)
975-
#define regcppush(a) S_regcppush(aTHX_ a)
975+
#define regcppush(a,b) S_regcppush(aTHX_ a,b)
976976
#define reghop3 S_reghop3
977977
#define reghopmaybe3 S_reghopmaybe3
978978
#define reginclass(a,b,c,d,e) S_reginclass(aTHX_ a,b,c,d,e)
@@ -1173,7 +1173,8 @@
11731173
#define parse_unicode_opts(a) Perl_parse_unicode_opts(aTHX_ a)
11741174
#define parser_free(a) Perl_parser_free(aTHX_ a)
11751175
#define peep(a) Perl_peep(aTHX_ a)
1176-
#define pmruntime(a,b,c) Perl_pmruntime(aTHX_ a,b,c)
1176+
#define pmruntime(a,b,c,d) Perl_pmruntime(aTHX_ a,b,c,d)
1177+
#define re_op_compile(a,b,c,d,e,f,g,h) Perl_re_op_compile(aTHX_ a,b,c,d,e,f,g,h)
11771178
#define refcounted_he_chain_2hv(a,b) Perl_refcounted_he_chain_2hv(aTHX_ a,b)
11781179
#define refcounted_he_fetch_pv(a,b,c,d) Perl_refcounted_he_fetch_pv(aTHX_ a,b,c,d)
11791180
#define refcounted_he_fetch_pvn(a,b,c,d,e) Perl_refcounted_he_fetch_pvn(aTHX_ a,b,c,d,e)
@@ -1464,7 +1465,7 @@
14641465
#define destroy_matcher(a) S_destroy_matcher(aTHX_ a)
14651466
#define do_smartmatch(a,b,c) S_do_smartmatch(aTHX_ a,b,c)
14661467
#define docatch(a) S_docatch(aTHX_ a)
1467-
#define doeval(a,b,c,d,e) S_doeval(aTHX_ a,b,c,d,e)
1468+
#define doeval(a,b,c,d) S_doeval(aTHX_ a,b,c,d)
14681469
#define dofindlabel(a,b,c,d,e,f) S_dofindlabel(aTHX_ a,b,c,d,e,f)
14691470
#define doparseform(a) S_doparseform(aTHX_ a)
14701471
#define dopoptoeval(a) S_dopoptoeval(aTHX_ a)
@@ -1584,7 +1585,7 @@
15841585
#define scan_ident(a,b,c,d,e) S_scan_ident(aTHX_ a,b,c,d,e)
15851586
#define scan_inputsymbol(a) S_scan_inputsymbol(aTHX_ a)
15861587
#define scan_pat(a,b) S_scan_pat(aTHX_ a,b)
1587-
#define scan_str(a,b,c) S_scan_str(aTHX_ a,b,c)
1588+
#define scan_str(a,b,c,d) S_scan_str(aTHX_ a,b,c,d)
15881589
#define scan_subst(a) S_scan_subst(aTHX_ a)
15891590
#define scan_trans(a) S_scan_trans(aTHX_ a)
15901591
#define scan_word(a,b,c,d,e) S_scan_word(aTHX_ a,b,c,d,e)

embedvar.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@
277277
#define PL_regdummy (vTHX->Iregdummy)
278278
#define PL_regex_pad (vTHX->Iregex_pad)
279279
#define PL_regex_padav (vTHX->Iregex_padav)
280-
#define PL_reginterp_cnt (vTHX->Ireginterp_cnt)
281280
#define PL_registered_mros (vTHX->Iregistered_mros)
282281
#define PL_regmatch_slab (vTHX->Iregmatch_slab)
283282
#define PL_regmatch_state (vTHX->Iregmatch_state)

ext/B/B.pm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,10 @@ Since Perl 5.9.5
11631163
11641164
Only when perl was compiled with ithreads.
11651165
1166+
=item code_list
1167+
1168+
Since perl 5.17.1
1169+
11661170
=back
11671171
11681172
=head2 B::SVOP METHOD

ext/B/B.xs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ threadsv_names()
864864
#define OP_private_ix U8p | offsetof(struct op, op_private)
865865

866866
#define PMOP_pmflags_ix U32p | offsetof(struct pmop, op_pmflags)
867+
#define PMOP_code_list_ix OPp | offsetof(struct pmop, op_code_list)
867868

868869
#ifdef USE_ITHREADS
869870
#define PMOP_pmoffset_ix IVp | offsetof(struct pmop, op_pmoffset)
@@ -922,6 +923,7 @@ next(o)
922923
B::LOOP::nextop = LOOP_nextop_ix
923924
B::LOOP::lastop = LOOP_lastop_ix
924925
B::PMOP::pmflags = PMOP_pmflags_ix
926+
B::PMOP::code_list = PMOP_code_list_ix
925927
B::SVOP::sv = SVOP_sv_ix
926928
B::SVOP::gv = SVOP_gv_ix
927929
B::PADOP::padix = PADOP_padix_ix

ext/Devel-Peek/t/Peek.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,15 +349,15 @@ do_test('reference to regexp',
349349
MINLENRET = 3
350350
GOFS = 0
351351
PRE_PREFIX = 4
352-
SEEN_EVALS = 0
353352
SUBLEN = 0
354353
SUBBEG = 0x0
355354
ENGINE = $ADDR
356355
MOTHER_RE = $ADDR
357356
PAREN_NAMES = 0x0
358357
SUBSTRS = $ADDR
359358
PPRIVATE = $ADDR
360-
OFFS = $ADDR'
359+
OFFS = $ADDR
360+
QR_ANONCV = 0x0'
361361
));
362362
} else {
363363
do_test('reference to regexp',

ext/re/re.pm

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package re;
44
use strict;
55
use warnings;
66

7-
our $VERSION = "0.19";
7+
our $VERSION = "0.20";
88
our @ISA = qw(Exporter);
99
our @EXPORT_OK = ('regmust',
1010
qw(is_regexp regexp_pattern
@@ -284,8 +284,9 @@ other transformations.
284284
285285
When C<use re 'eval'> is in effect, a regexp is allowed to contain
286286
C<(?{ ... })> zero-width assertions and C<(??{ ... })> postponed
287-
subexpressions, even if the regular expression contains
288-
variable interpolation. That is normally disallowed, since it is a
287+
subexpressions that are derived from variable interpolation, rather than
288+
appearing literally within the regexp. That is normally disallowed, since
289+
it is a
289290
potential security risk. Note that this pragma is ignored when the regular
290291
expression is obtained from tainted data, i.e. evaluation is always
291292
disallowed with tainted regular expressions. See L<perlre/(?{ code })>

ext/re/re.xs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
START_EXTERN_C
1313

1414
extern REGEXP* my_re_compile (pTHX_ SV * const pattern, const U32 pm_flags);
15+
extern REGEXP* my_re_op_compile (pTHX_ SV ** const patternp, int pat_count,
16+
OP *expr, const regexp_engine* eng, REGEXP *VOL old_re,
17+
bool *is_bare_re, U32 rx_flags, U32 pm_flags);
18+
1519
extern I32 my_regexec (pTHX_ REGEXP * const prog, char* stringarg, char* strend,
1620
char* strbeg, I32 minend, SV* screamer,
1721
void* data, U32 flags);
@@ -57,8 +61,9 @@ const struct regexp_engine my_reg_engine = {
5761
my_reg_named_buff_iter,
5862
my_reg_qr_package,
5963
#if defined(USE_ITHREADS)
60-
my_regdupe
64+
my_regdupe,
6165
#endif
66+
my_re_op_compile,
6267
};
6368

6469
MODULE = re PACKAGE = re

ext/re/re_top.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define Perl_regprop my_regprop
1414
#define Perl_re_intuit_start my_re_intuit_start
1515
#define Perl_re_compile my_re_compile
16+
#define Perl_re_op_compile my_re_op_compile
1617
#define Perl_regfree_internal my_regfree
1718
#define Perl_re_intuit_string my_re_intuit_string
1819
#define Perl_regdupe_internal my_regdupe

ext/re/t/reflags.t

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,35 @@ BEGIN {
1010

1111
use strict;
1212

13-
use Test::More tests => 53;
13+
use Test::More tests => 62;
1414

1515
my @flags = qw( a d l u );
1616

1717
use re '/i';
1818
ok "Foo" =~ /foo/, 'use re "/i"';
19+
ok "Foo" =~ /(??{'foo'})/, 'use re "/i" (??{})';
1920
no re '/i';
2021
ok "Foo" !~ /foo/, 'no re "/i"';
22+
ok "Foo" !~ /(??{'foo'})/, 'no re "/i" (??{})';
2123
use re '/x';
2224
ok "foo" =~ / foo /, 'use re "/x"';
25+
ok "foo" =~ / (??{' foo '}) /, 'use re "/x" (??{})';
2326
no re '/x';
2427
ok "foo" !~ / foo /, 'no re "/x"';
28+
ok "foo" !~ /(??{' foo '})/, 'no re "/x" (??{})';
29+
ok "foo" !~ / (??{'foo'}) /, 'no re "/x" (??{})';
2530
use re '/s';
2631
ok "\n" =~ /./, 'use re "/s"';
32+
ok "\n" =~ /(??{'.'})/, 'use re "/s" (??{})';
2733
no re '/s';
2834
ok "\n" !~ /./, 'no re "/s"';
35+
ok "\n" !~ /(??{'.'})/, 'no re "/s" (??{})';
2936
use re '/m';
3037
ok "\nfoo" =~ /^foo/, 'use re "/m"';
38+
ok "\nfoo" =~ /(??{'^'})foo/, 'use re "/m" (??{})';
3139
no re '/m';
3240
ok "\nfoo" !~ /^foo/, 'no re "/m"';
41+
ok "\nfoo" !~ /(??{'^'})foo/, 'no re "/m" (??{})';
3342

3443
use re '/xism';
3544
ok qr// =~ /(?=.*x)(?=.*i)(?=.*s)(?=.*m)/, 'use re "/multiple"';

0 commit comments

Comments
 (0)