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=7vno3fVuppO8Ro&#5QO7l$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