|
|
4dad76 |
From fd30a7c49a661aecfb361045646da264cdadea8f Mon Sep 17 00:00:00 2001
|
|
|
4dad76 |
From: Karl Williamson <khw@cpan.org>
|
|
|
4dad76 |
Date: Fri, 23 Aug 2019 12:40:24 -0600
|
|
|
4dad76 |
Subject: [PATCH] PATCH: [perl #134329] Use after free in regcomp.c
|
|
|
4dad76 |
MIME-Version: 1.0
|
|
|
4dad76 |
Content-Type: text/plain; charset=UTF-8
|
|
|
4dad76 |
Content-Transfer-Encoding: 8bit
|
|
|
4dad76 |
|
|
|
4dad76 |
A compiled regex is composed of nodes, forming a linked list, with
|
|
|
4dad76 |
normally a maximum of 16 bits used to specify the offset of the next
|
|
|
4dad76 |
link. For patterns that require more space than this, the nodes that
|
|
|
4dad76 |
jump around are replaced with ones that have wider offsets. Most nodes
|
|
|
4dad76 |
are unaffected, as they just contain the offset of the next node, and
|
|
|
4dad76 |
that number is always small. The jump nodes are the ones affected.
|
|
|
4dad76 |
|
|
|
4dad76 |
When compiling a pattern, the 16 bit mechanism is used, until it
|
|
|
4dad76 |
overflows, at which point the pattern is recompiled with the long jumps
|
|
|
4dad76 |
instead.
|
|
|
4dad76 |
|
|
|
4dad76 |
When I rewrote the compiler last year to make it generally one pass, I
|
|
|
4dad76 |
noticed a lot of the cases where a node was added didn't check if the
|
|
|
4dad76 |
result overflowed (the function that does this returns FALSE in that
|
|
|
4dad76 |
case). I presumed the prior authors knew better, and did not change
|
|
|
4dad76 |
things, except to put in a bogus value in the link (offset) field that
|
|
|
4dad76 |
should cause a crash if it were used. That's what's happening in this
|
|
|
4dad76 |
ticket.
|
|
|
4dad76 |
|
|
|
4dad76 |
But seeing this example, it's clear that the return value should be
|
|
|
4dad76 |
checked every time, because you can reach the limit at any time. This
|
|
|
4dad76 |
commit changes to do that, and to require the function's return value to
|
|
|
4dad76 |
not be ignored, to guard against future changes.
|
|
|
4dad76 |
|
|
|
4dad76 |
My guess is that the reason it generally worked when there were multiple
|
|
|
4dad76 |
passes is that the first pass didn't do anything except count space, and
|
|
|
4dad76 |
that at some point before the end of the pass the return value did get
|
|
|
4dad76 |
checked, so by the time the nodes were allocated for real, it knew
|
|
|
4dad76 |
enough to use the long jumps.
|
|
|
4dad76 |
|
|
|
4dad76 |
Petr Písař: Ported to 5.30.0 from
|
|
|
4dad76 |
3b2e5620ed4a6b341f97ffd1d4b6466cc2c4bc5b.
|
|
|
4dad76 |
|
|
|
4dad76 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
4dad76 |
---
|
|
|
4dad76 |
MANIFEST | 1 +
|
|
|
4dad76 |
embed.fnc | 4 +-
|
|
|
4dad76 |
proto.h | 8 ++-
|
|
|
4dad76 |
regcomp.c | 109 ++++++++++++++++++++++++++++-----------
|
|
|
4dad76 |
t/re/bigfuzzy_not_utf8.t | Bin 0 -> 36399 bytes
|
|
|
4dad76 |
5 files changed, 88 insertions(+), 34 deletions(-)
|
|
|
4dad76 |
create mode 100644 t/re/bigfuzzy_not_utf8.t
|
|
|
4dad76 |
|
|
|
4dad76 |
diff --git a/MANIFEST b/MANIFEST
|
|
|
4dad76 |
index 10e2cc0..cc24cd7 100644
|
|
|
4dad76 |
--- a/MANIFEST
|
|
|
4dad76 |
+++ b/MANIFEST
|
|
|
4dad76 |
@@ -5839,6 +5839,7 @@ t/porting/test_bootstrap.t Test that the instructions for test bootstrapping are
|
|
|
4dad76 |
t/porting/utils.t Check that utility scripts still compile
|
|
|
4dad76 |
t/re/alpha_assertions.t See if things like '(*postive_lookahed:...) work properly
|
|
|
4dad76 |
t/re/anyof.t See if bracketed char classes [...] compile properly
|
|
|
4dad76 |
+t/re/bigfuzzy_not_utf8.t Big and ugly tests not storable as UTF-8
|
|
|
4dad76 |
t/re/charset.t See if regex modifiers like /d, /u work properly
|
|
|
4dad76 |
t/re/fold_grind.pl Core file to see if regex case folding works properly
|
|
|
4dad76 |
t/re/fold_grind_8.t Wrapper for fold_grind.pl for /l testing with a UTF-8 locale
|
|
|
4dad76 |
diff --git a/embed.fnc b/embed.fnc
|
|
|
4dad76 |
index c977d39..c2c5f16 100644
|
|
|
4dad76 |
--- a/embed.fnc
|
|
|
4dad76 |
+++ b/embed.fnc
|
|
|
4dad76 |
@@ -2427,7 +2427,7 @@ Es |void |reginsert |NN RExC_state_t *pRExC_state \
|
|
|
4dad76 |
|const U8 op \
|
|
|
4dad76 |
|const regnode_offset operand \
|
|
|
4dad76 |
|const U32 depth
|
|
|
4dad76 |
-Es |bool |regtail |NN RExC_state_t * pRExC_state \
|
|
|
4dad76 |
+EsR |bool |regtail |NN RExC_state_t * pRExC_state \
|
|
|
4dad76 |
|NN const regnode_offset p \
|
|
|
4dad76 |
|NN const regnode_offset val \
|
|
|
4dad76 |
|const U32 depth
|
|
|
4dad76 |
@@ -2561,7 +2561,7 @@ Es |void |dump_trie_interim_list|NN const struct _reg_trie_data *trie\
|
|
|
4dad76 |
Es |void |dump_trie_interim_table|NN const struct _reg_trie_data *trie\
|
|
|
4dad76 |
|NULLOK HV* widecharmap|NN AV *revcharmap\
|
|
|
4dad76 |
|U32 next_alloc|U32 depth
|
|
|
4dad76 |
-Es |bool |regtail_study |NN RExC_state_t *pRExC_state \
|
|
|
4dad76 |
+EsR |bool |regtail_study |NN RExC_state_t *pRExC_state \
|
|
|
4dad76 |
|NN regnode_offset p|NN const regnode_offset val|U32 depth
|
|
|
4dad76 |
# endif
|
|
|
4dad76 |
#endif
|
|
|
4dad76 |
diff --git a/proto.h b/proto.h
|
|
|
4dad76 |
index e0ea55b..2ef7ce2 100644
|
|
|
4dad76 |
--- a/proto.h
|
|
|
4dad76 |
+++ b/proto.h
|
|
|
4dad76 |
@@ -4457,9 +4457,11 @@ PERL_CALLCONV int Perl_re_indentf(pTHX_ const char *fmt, U32 depth, ...);
|
|
|
4dad76 |
assert(fmt)
|
|
|
4dad76 |
STATIC void S_regdump_extflags(pTHX_ const char *lead, const U32 flags);
|
|
|
4dad76 |
STATIC void S_regdump_intflags(pTHX_ const char *lead, const U32 flags);
|
|
|
4dad76 |
-STATIC bool S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode_offset p, const regnode_offset val, U32 depth);
|
|
|
4dad76 |
+STATIC bool S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode_offset p, const regnode_offset val, U32 depth)
|
|
|
4dad76 |
+ __attribute__warn_unused_result__;
|
|
|
4dad76 |
#define PERL_ARGS_ASSERT_REGTAIL_STUDY \
|
|
|
4dad76 |
assert(pRExC_state); assert(p); assert(val)
|
|
|
4dad76 |
+
|
|
|
4dad76 |
# endif
|
|
|
4dad76 |
# if defined(PERL_IN_REGEXEC_C)
|
|
|
4dad76 |
STATIC void S_debug_start_match(pTHX_ const REGEXP *prog, const bool do_utf8, const char *start, const char *end, const char *blurb);
|
|
|
4dad76 |
@@ -5599,9 +5601,11 @@ STATIC regnode_offset S_regnode_guts(pTHX_ RExC_state_t *pRExC_state, const U8 o
|
|
|
4dad76 |
STATIC regnode_offset S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth);
|
|
|
4dad76 |
#define PERL_ARGS_ASSERT_REGPIECE \
|
|
|
4dad76 |
assert(pRExC_state); assert(flagp)
|
|
|
4dad76 |
-STATIC bool S_regtail(pTHX_ RExC_state_t * pRExC_state, const regnode_offset p, const regnode_offset val, const U32 depth);
|
|
|
4dad76 |
+STATIC bool S_regtail(pTHX_ RExC_state_t * pRExC_state, const regnode_offset p, const regnode_offset val, const U32 depth)
|
|
|
4dad76 |
+ __attribute__warn_unused_result__;
|
|
|
4dad76 |
#define PERL_ARGS_ASSERT_REGTAIL \
|
|
|
4dad76 |
assert(pRExC_state); assert(p); assert(val)
|
|
|
4dad76 |
+
|
|
|
4dad76 |
STATIC void S_scan_commit(pTHX_ const RExC_state_t *pRExC_state, struct scan_data_t *data, SSize_t *minlenp, int is_inf);
|
|
|
4dad76 |
#define PERL_ARGS_ASSERT_SCAN_COMMIT \
|
|
|
4dad76 |
assert(pRExC_state); assert(data); assert(minlenp)
|
|
|
4dad76 |
diff --git a/regcomp.c b/regcomp.c
|
|
|
4dad76 |
index dfc22bc..b93fbe7 100644
|
|
|
4dad76 |
--- a/regcomp.c
|
|
|
4dad76 |
+++ b/regcomp.c
|
|
|
4dad76 |
@@ -11307,10 +11307,15 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
return 0;
|
|
|
4dad76 |
}
|
|
|
4dad76 |
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, atomic);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, atomic)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
|
|
|
4dad76 |
- REGTAIL(pRExC_state, atomic,
|
|
|
4dad76 |
- reg_node(pRExC_state, SRCLOSE));
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, atomic, reg_node(pRExC_state,
|
|
|
4dad76 |
+ SRCLOSE)))
|
|
|
4dad76 |
+ {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
|
|
|
4dad76 |
RExC_in_script_run = 0;
|
|
|
4dad76 |
return ret;
|
|
|
4dad76 |
@@ -11769,7 +11774,9 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
RExC_flags & RXf_PMf_COMPILETIME
|
|
|
4dad76 |
);
|
|
|
4dad76 |
FLAGS(REGNODE_p(ret)) = 2;
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, eval);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, eval)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
/* deal with the length of this later - MJD */
|
|
|
4dad76 |
return ret;
|
|
|
4dad76 |
}
|
|
|
4dad76 |
@@ -11822,7 +11829,9 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
|
|
|
4dad76 |
tail = reg(pRExC_state, 1, &flag, depth+1);
|
|
|
4dad76 |
RETURN_FAIL_ON_RESTART(flag, flagp);
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, tail);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, tail)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
goto insert_if;
|
|
|
4dad76 |
}
|
|
|
4dad76 |
else if ( RExC_parse[0] == '<' /* (?(<NAME>)...) */
|
|
|
4dad76 |
@@ -11914,15 +11923,22 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
}
|
|
|
4dad76 |
nextchar(pRExC_state);
|
|
|
4dad76 |
insert_if:
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, reganode(pRExC_state, IFTHEN, 0));
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, reganode(pRExC_state,
|
|
|
4dad76 |
+ IFTHEN, 0)))
|
|
|
4dad76 |
+ {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
br = regbranch(pRExC_state, &flags, 1, depth+1);
|
|
|
4dad76 |
if (br == 0) {
|
|
|
4dad76 |
RETURN_FAIL_ON_RESTART(flags,flagp);
|
|
|
4dad76 |
FAIL2("panic: regbranch returned failure, flags=%#" UVxf,
|
|
|
4dad76 |
(UV) flags);
|
|
|
4dad76 |
} else
|
|
|
4dad76 |
- REGTAIL(pRExC_state, br, reganode(pRExC_state,
|
|
|
4dad76 |
- LONGJMP, 0));
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, br, reganode(pRExC_state,
|
|
|
4dad76 |
+ LONGJMP, 0)))
|
|
|
4dad76 |
+ {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
c = UCHARAT(RExC_parse);
|
|
|
4dad76 |
nextchar(pRExC_state);
|
|
|
4dad76 |
if (flags&HASWIDTH)
|
|
|
4dad76 |
@@ -11939,7 +11955,9 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
FAIL2("panic: regbranch returned failure, flags=%#" UVxf,
|
|
|
4dad76 |
(UV) flags);
|
|
|
4dad76 |
}
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, lastbr);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, lastbr)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
if (flags&HASWIDTH)
|
|
|
4dad76 |
*flagp |= HASWIDTH;
|
|
|
4dad76 |
c = UCHARAT(RExC_parse);
|
|
|
4dad76 |
@@ -11954,16 +11972,26 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
vFAIL("Switch (?(condition)... contains too many branches");
|
|
|
4dad76 |
}
|
|
|
4dad76 |
ender = reg_node(pRExC_state, TAIL);
|
|
|
4dad76 |
- REGTAIL(pRExC_state, br, ender);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, br, ender)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
if (lastbr) {
|
|
|
4dad76 |
- REGTAIL(pRExC_state, lastbr, ender);
|
|
|
4dad76 |
- REGTAIL(pRExC_state, REGNODE_OFFSET(
|
|
|
4dad76 |
- NEXTOPER(
|
|
|
4dad76 |
- NEXTOPER(REGNODE_p(lastbr)))),
|
|
|
4dad76 |
- ender);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, lastbr, ender)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state,
|
|
|
4dad76 |
+ REGNODE_OFFSET(
|
|
|
4dad76 |
+ NEXTOPER(
|
|
|
4dad76 |
+ NEXTOPER(REGNODE_p(lastbr)))),
|
|
|
4dad76 |
+ ender))
|
|
|
4dad76 |
+ {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
}
|
|
|
4dad76 |
else
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, ender);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, ender)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
#if 0 /* Removing this doesn't cause failures in the test suite -- khw */
|
|
|
4dad76 |
RExC_size++; /* XXX WHY do we need this?!!
|
|
|
4dad76 |
For large programs it seems to be required
|
|
|
4dad76 |
@@ -12113,7 +12141,9 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
*flagp |= flags&SIMPLE;
|
|
|
4dad76 |
}
|
|
|
4dad76 |
if (is_open) { /* Starts with OPEN. */
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, br); /* OPEN -> first. */
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, br)) { /* OPEN -> first. */
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
}
|
|
|
4dad76 |
else if (paren != '?') /* Not Conditional */
|
|
|
4dad76 |
ret = br;
|
|
|
4dad76 |
@@ -12121,12 +12151,15 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
lastbr = br;
|
|
|
4dad76 |
while (*RExC_parse == '|') {
|
|
|
4dad76 |
if (RExC_use_BRANCHJ) {
|
|
|
4dad76 |
+ bool shut_gcc_up;
|
|
|
4dad76 |
+
|
|
|
4dad76 |
ender = reganode(pRExC_state, LONGJMP, 0);
|
|
|
4dad76 |
|
|
|
4dad76 |
/* Append to the previous. */
|
|
|
4dad76 |
- REGTAIL(pRExC_state,
|
|
|
4dad76 |
- REGNODE_OFFSET(NEXTOPER(NEXTOPER(REGNODE_p(lastbr)))),
|
|
|
4dad76 |
- ender);
|
|
|
4dad76 |
+ shut_gcc_up = REGTAIL(pRExC_state,
|
|
|
4dad76 |
+ REGNODE_OFFSET(NEXTOPER(NEXTOPER(REGNODE_p(lastbr)))),
|
|
|
4dad76 |
+ ender);
|
|
|
4dad76 |
+ PERL_UNUSED_VAR(shut_gcc_up);
|
|
|
4dad76 |
}
|
|
|
4dad76 |
nextchar(pRExC_state);
|
|
|
4dad76 |
if (freeze_paren) {
|
|
|
4dad76 |
@@ -12237,9 +12270,10 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp, U32 depth)
|
|
|
4dad76 |
is_nothing= 0;
|
|
|
4dad76 |
}
|
|
|
4dad76 |
else if (op == BRANCHJ) {
|
|
|
4dad76 |
- REGTAIL_STUDY(pRExC_state,
|
|
|
4dad76 |
- REGNODE_OFFSET(NEXTOPER(NEXTOPER(br))),
|
|
|
4dad76 |
- ender);
|
|
|
4dad76 |
+ bool shut_gcc_up = REGTAIL_STUDY(pRExC_state,
|
|
|
4dad76 |
+ REGNODE_OFFSET(NEXTOPER(NEXTOPER(br))),
|
|
|
4dad76 |
+ ender);
|
|
|
4dad76 |
+ PERL_UNUSED_VAR(shut_gcc_up);
|
|
|
4dad76 |
/* for now we always disable this optimisation * /
|
|
|
4dad76 |
if ( OP(NEXTOPER(NEXTOPER(br))) != NOTHING
|
|
|
4dad76 |
|| regnext(NEXTOPER(NEXTOPER(br))) != REGNODE_p(ender))
|
|
|
4dad76 |
@@ -12551,7 +12585,9 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
|
|
|
4dad76 |
const regnode_offset w = reg_node(pRExC_state, WHILEM);
|
|
|
4dad76 |
|
|
|
4dad76 |
FLAGS(REGNODE_p(w)) = 0;
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, w);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, w)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
if (RExC_use_BRANCHJ) {
|
|
|
4dad76 |
reginsert(pRExC_state, LONGJMP, ret, depth+1);
|
|
|
4dad76 |
reginsert(pRExC_state, NOTHING, ret, depth+1);
|
|
|
4dad76 |
@@ -12566,7 +12602,11 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
|
|
|
4dad76 |
if (RExC_use_BRANCHJ)
|
|
|
4dad76 |
NEXT_OFF(REGNODE_p(ret)) = 3; /* Go over NOTHING to
|
|
|
4dad76 |
LONGJMP. */
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, reg_node(pRExC_state, NOTHING));
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, reg_node(pRExC_state,
|
|
|
4dad76 |
+ NOTHING)))
|
|
|
4dad76 |
+ {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
RExC_whilem_seen++;
|
|
|
4dad76 |
MARK_NAUGHTY_EXP(1, 4); /* compound interest */
|
|
|
4dad76 |
}
|
|
|
4dad76 |
@@ -12638,16 +12678,22 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
|
|
|
4dad76 |
if (*RExC_parse == '?') {
|
|
|
4dad76 |
nextchar(pRExC_state);
|
|
|
4dad76 |
reginsert(pRExC_state, MINMOD, ret, depth+1);
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, ret + NODE_STEP_REGNODE);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, ret + NODE_STEP_REGNODE)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
}
|
|
|
4dad76 |
else if (*RExC_parse == '+') {
|
|
|
4dad76 |
regnode_offset ender;
|
|
|
4dad76 |
nextchar(pRExC_state);
|
|
|
4dad76 |
ender = reg_node(pRExC_state, SUCCEED);
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, ender);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, ender)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
reginsert(pRExC_state, SUSPEND, ret, depth+1);
|
|
|
4dad76 |
ender = reg_node(pRExC_state, TAIL);
|
|
|
4dad76 |
- REGTAIL(pRExC_state, ret, ender);
|
|
|
4dad76 |
+ if (! REGTAIL(pRExC_state, ret, ender)) {
|
|
|
4dad76 |
+ REQUIRE_BRANCHJ(flagp, 0);
|
|
|
4dad76 |
+ }
|
|
|
4dad76 |
}
|
|
|
4dad76 |
|
|
|
4dad76 |
if (ISMULT2(RExC_parse)) {
|
|
|
4dad76 |
@@ -19815,8 +19861,8 @@ S_regtail(pTHX_ RExC_state_t * pRExC_state,
|
|
|
4dad76 |
}
|
|
|
4dad76 |
else {
|
|
|
4dad76 |
if (val - scan > U16_MAX) {
|
|
|
4dad76 |
- /* Since not all callers check the return value, populate this with
|
|
|
4dad76 |
- * something that won't loop and will likely lead to a crash if
|
|
|
4dad76 |
+ /* Populate this with something that won't loop and will likely
|
|
|
4dad76 |
+ * lead to a crash if the caller ignores the failure return, and
|
|
|
4dad76 |
* execution continues */
|
|
|
4dad76 |
NEXT_OFF(REGNODE_p(scan)) = U16_MAX;
|
|
|
4dad76 |
return FALSE;
|
|
|
4dad76 |
@@ -19927,6 +19973,9 @@ S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode_offset p,
|
|
|
4dad76 |
}
|
|
|
4dad76 |
else {
|
|
|
4dad76 |
if (val - scan > U16_MAX) {
|
|
|
4dad76 |
+ /* Populate this with something that won't loop and will likely
|
|
|
4dad76 |
+ * lead to a crash if the caller ignores the failure return, and
|
|
|
4dad76 |
+ * execution continues */
|
|
|
4dad76 |
NEXT_OFF(REGNODE_p(scan)) = U16_MAX;
|
|
|
4dad76 |
return FALSE;
|
|
|
4dad76 |
}
|
|
|
4dad76 |
diff --git a/t/re/bigfuzzy_not_utf8.t b/t/re/bigfuzzy_not_utf8.t
|
|
|
4dad76 |
new file mode 100644
|
|
|
4dad76 |
index 0000000000000000000000000000000000000000..b4dfd150a9297172af5d8e7811357fd68931f8d7
|
|
|
4dad76 |
GIT binary patch
|
|
|
4dad76 |
literal 36399
|
|
|
4dad76 |
zcmeI5y>Ht_6u>V)vj`|)bnw`ot)P-@MMCTpNTQ@6nzlsHpvaKGfa6%8#FNC9CKZxu
|
|
|
4dad76 |
z;)Jf$YRJ%zoeHDqo_|0?hWr89EXQ;I1&?0XN7}J$MN%l4pVm7V_T9aA@8fqzil1_F
|
|
|
4dad76 |
zE|;$}O->{eN&28B=@fnhT2nU|t*9E+ShXPw8fDMw8q;-2Rj9#qL#IYfFlbp&QU)zC
|
|
|
4dad76 |
zsvD}tL@Ma?;e+olU(13qL4mf$Xi2KlMpfR-(n>>?sal~`K`RMWM$0up6UqkD^enA1
|
|
|
4dad76 |
zg=vB;ZywbQuvXdxGnK~k=b({GBpSNyN0Z7%!KptLG(}RXdLfa}8zrhWl%f+Fv@e
|
|
|
4dad76 |
z7QF(MZ@%O2{zzXWD3o$dlr)+$QdFwY%c5N?I0B75X-E+19aX7F)dH0^>Z)eEZ=O;~
|
|
|
4dad76 |
zoje1d1%IQ=tmzSkdDoay2=T|Pz
|
|
|
4dad76 |
zo*8+Kr80%Y79{wyR4)RabV^adFWpeZh73a5P-K`EDzb{C0J1N?-Bg5osvt7$#*LDy
|
|
|
4dad76 |
z8pU1*;Hb;O`}w=|H2|VCNgvil!C)|-F!4`oOre4(0@l39WM)9+aK3^6G2ryE+cJd2
|
|
|
4dad76 |
zG%)O}9%o(Xh5+npOk+9dJvA{f4-S
|
|
|
4dad76 |
zS%FnoE840>Nl&MqX!&&dnrWK5-2KkXUdJ@kJhZYzBs1%)nFU8yw#)YRc86bC;+Jl5
|
|
|
4dad76 |
zgy&7Z`^Fw(?OiZUet&)S)$APMGYhtb_713ZrNwu<++Ih39!HYq+wJzw?PH0VT{$4+
|
|
|
4dad76 |
zz%lmLw7_MJYpy#@2q4sQ7fUP%j9esxG8j3)cOk6*w(m~R0TQqY5H30#e)2t(Pe1U0
|
|
|
4dad76 |
zo7x9RuwyuZKZc9WF8Sr`COoz9_eZT+t&ggp!nq?r$P9^7Qf{`Z-{X`J#)<@xfTsj3
|
|
|
4dad76 |
zt7*Z}u%|ZB*f}Q9ILEnRY6A%n(u&6pLLV6Zhn*Je^046bHe3TpU@8gBV?hE)AbtcU
|
|
|
4dad76 |
z+*`#j(Lf`1Pqq2ly)J6Thrs2aLgj*Tgns-Zu;!m>A1&i8UmxMd)HGfL@L=Np^}xmu
|
|
|
4dad76 |
z6KnnbWTw9d+eiQj_)Fjmf6b$HBoG*ZvmFNFos+;OYFZqXdWnYd{P*jg`)Jij({(%|
|
|
|
4dad76 |
z`6Q@2v~b4IiYzkMz+$L)vsWgF{`mxB#u(y$sg7Y3RpU)yZB+QhQ9`d|Ekc6YFM1X7
|
|
|
4dad76 |
zv7KL!Yu;A|z5IoJ9um0Yp{;0|@_teFTYTByaiWdaEl
|
|
|
4dad76 |
zPFzulaPT39=F90?E5wAR)%Dpf=7vno3fVuppO8RoQO7l$E%7!gQ^8*6kwlia=^
|
|
|
4dad76 |
z7B0VddLMEq9(*#931rOF{~Aj_u33(iBr5k4z;mpAB2(G^Zz{9Kq>+G^1Vp#S{&b=E
|
|
|
4dad76 |
zj|&}JWy0IK6Ap73lq)qn<QR$RqGeqiso;SyjOXJ#2pdfx0VLp>z?y5#A&T&w
|
|
|
4dad76 |
zUiJx|1$vwg0zrO}lpkL`u+~3K_
|
|
|
4dad76 |
zicZin*SoHPf#Jg+1F=k5r(avNUv|&?^aT4NA<j}5>#6r1;mt7IkM
|
|
|
4dad76 |
zl=}L=Xoe&f=@$t@+-3rNH|>W2eFfxdF(5w^x}jvkffEfIvgHNTjXV5+K%<*L3ET_R
|
|
|
4dad76 |
z+c|c&wL;;PQ@lgr#v_H=NB{{Sfw2f&z<1F4c?Err>gK7){ur^11cD`i`-xzApY~Qf
|
|
|
4dad76 |
z-Soco%zKmLS;Xfudc5$tj2??=s^NXSD9!fSp38_*Cb5m>t!bHAQk&zN(xREQTJ4>c
|
|
|
4dad76 |
zC4OI8w7BN_>Y<Q`P|Yl)JEqC+?<=onyWQ@36FPXvI!i<{<A|?8t9(>=zWZjEyWg?)
|
|
|
4dad76 |
z-~n%be|`1U>>S}U3wvP0@z9kP-|cdH9RYeANt%btP&>Dm_#=s#T{$4+fFnF_9>oX|
|
|
|
4dad76 |
zooo&c`N+|sIY^}|4akg;3*^W-WYBK!OJAAU-%N9Mt_49ZzRWCquG}WPRkz@uPUllu
|
|
|
4dad76 |
jIzOMKFSg+CqdL=Mn!K`nb$RLf<M~V>L7{9Vwi5pX0LDXb
|
|
|
4dad76 |
|
|
|
4dad76 |
literal 0
|
|
|
4dad76 |
HcmV?d00001
|
|
|
4dad76 |
|
|
|
4dad76 |
--
|
|
|
4dad76 |
2.21.0
|
|
|
4dad76 |
|