diff options
-rw-r--r-- | embed.fnc | 1 | ||||
-rw-r--r-- | embed.h | 2 | ||||
-rw-r--r-- | pod/perldelta.pod | 6 | ||||
-rw-r--r-- | pod/perldiag.pod | 7 | ||||
-rw-r--r-- | proto.h | 2 | ||||
-rw-r--r-- | regcomp.c | 14 | ||||
-rw-r--r-- | t/re/reg_mesg.t | 4 |
7 files changed, 25 insertions, 11 deletions
@@ -2174,6 +2174,7 @@ Es |bool |grok_bslash_N |NN RExC_state_t *pRExC_state \ |NULLOK UV *code_point_p \ |NULLOK int* cp_count \ |NN I32 *flagp \ + |const bool strict \ |const U32 depth Es |void |reginsert |NN RExC_state_t *pRExC_state \ |U8 op|NN regnode *opnd|U32 depth @@ -999,7 +999,7 @@ #define edit_distance S_edit_distance #define get_ANYOF_cp_list_for_ssc(a,b) S_get_ANYOF_cp_list_for_ssc(aTHX_ a,b) #define get_invlist_iter_addr S_get_invlist_iter_addr -#define grok_bslash_N(a,b,c,d,e,f) S_grok_bslash_N(aTHX_ a,b,c,d,e,f) +#define grok_bslash_N(a,b,c,d,e,f,g) S_grok_bslash_N(aTHX_ a,b,c,d,e,f,g) #define handle_named_backref(a,b,c,d) S_handle_named_backref(aTHX_ a,b,c,d) #define handle_possible_posix(a,b,c,d) S_handle_possible_posix(aTHX_ a,b,c,d) #define handle_regex_sets(a,b,c,d,e) S_handle_regex_sets(aTHX_ a,b,c,d,e) diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 5607b2efe7..55db093a1e 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -52,6 +52,12 @@ XXX For a release on a stable branch, this section aspires to be: [ List each incompatible change as a =head2 entry ] +=head2 C<qr/\N{}/> now disallowed under C<use re "strict"> + +An empty C<\N{}> makes no sense, but for backwards compatibility is +silently accepted as doing nothing. But now this is a fatal error under +the experimental feature L<re/'strict' mode>. + =head1 Deprecations XXX Any deprecated features, syntax, modules etc. should be listed here. diff --git a/pod/perldiag.pod b/pod/perldiag.pod index cc27016512..1e4760d246 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -7203,9 +7203,10 @@ Something Very Wrong. (F) Named Unicode character escapes (C<\N{...}>) may return a zero-length sequence. Such an escape was used in an extended character class, i.e. -C<(?[...])>, which is not permitted. Check that the correct escape has -been used, and the correct charnames handler is in scope. The S<<-- HERE> -shows whereabouts in the regular expression the problem was discovered. +C<(?[...])>, or under C<use re 'strict'>, which is not permitted. Check +that the correct escape has been used, and the correct charnames handler +is in scope. The S<<-- HERE> shows whereabouts in the regular +expression the problem was discovered. =back @@ -4747,7 +4747,7 @@ PERL_STATIC_INLINE STRLEN* S_get_invlist_iter_addr(SV* invlist) #define PERL_ARGS_ASSERT_GET_INVLIST_ITER_ADDR \ assert(invlist) -STATIC bool S_grok_bslash_N(pTHX_ RExC_state_t *pRExC_state, regnode** nodep, UV *code_point_p, int* cp_count, I32 *flagp, const U32 depth); +STATIC bool S_grok_bslash_N(pTHX_ RExC_state_t *pRExC_state, regnode** nodep, UV *code_point_p, int* cp_count, I32 *flagp, const bool strict, const U32 depth); #define PERL_ARGS_ASSERT_GROK_BSLASH_N \ assert(pRExC_state); assert(flagp) PERL_STATIC_INLINE regnode* S_handle_named_backref(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, char * parse_start, char ch); @@ -11394,6 +11394,7 @@ S_grok_bslash_N(pTHX_ RExC_state_t *pRExC_state, UV * code_point_p, int * cp_count, I32 * flagp, + const bool strict, const U32 depth ) { @@ -11543,6 +11544,10 @@ S_grok_bslash_N(pTHX_ RExC_state_t *pRExC_state, semantics */ if (endbrace == RExC_parse) { /* empty: \N{} */ + if (strict) { + RExC_parse++; /* Position after the "}" */ + vFAIL("Zero length \\N{}"); + } if (cp_count) { *cp_count = 0; } @@ -12422,6 +12427,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth) NULL, /* Don't need a count of how many code points */ flagp, + RExC_strict, depth) ) { break; @@ -12748,6 +12754,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth) NULL, /* Don't need a count of how many code points */ flagp, + RExC_strict, depth) ) { if (*flagp & NEED_UTF8) @@ -15529,6 +15536,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth, &value, /* Yes single value */ &cp_count, /* Multiple code pt count */ flagp, + strict, depth) ) { @@ -15541,11 +15549,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth, vFAIL("\\N in a character class must be a named character: \\N{...}"); } else if (cp_count == 0) { - if (strict) { - RExC_parse++; /* Position after the "}" */ - vFAIL("Zero length \\N{}"); - } - else if (PASS2) { + if (PASS2) { ckWARNreg(RExC_parse, "Ignoring zero length \\N{} in character class"); } diff --git a/t/re/reg_mesg.t b/t/re/reg_mesg.t index 6ec5d94534..d05922e341 100644 --- a/t/re/reg_mesg.t +++ b/t/re/reg_mesg.t @@ -295,7 +295,9 @@ my @death_only_under_strict = ( 'm/[\x{ABCDEFG}]/' => 'Illegal hexadecimal digit \'G\' ignored', => 'Non-hex character {#} m/[\x{ABCDEFG{#}}]/', 'm/[\N{}]/' => 'Ignoring zero length \\N{} in character class {#} m/[\\N{}{#}]/', - => 'Zero length \\N{} {#} m/[\\N{}]{#}/', + => 'Zero length \\N{} {#} m/[\\N{}{#}]/', + 'm/\N{}/' => "", + => 'Zero length \\N{} {#} m/\\N{}{#}/', "m'[\\y]\\x{100}'" => 'Unrecognized escape \y in character class passed through {#} m/[\y{#}]\x{100}/', => 'Unrecognized escape \y in character class {#} m/[\y{#}]\x{100}/', 'm/[a-\d]\x{100}/' => 'False [] range "a-\d" {#} m/[a-\d{#}]\x{100}/', |