[perl/f15] Count capturing parenthesis properly

Petr Pisar ppisar at fedoraproject.org
Mon May 14 12:38:56 UTC 2012


commit 1c93a0affe08d0d910d7093198cbc83a3965b4d0
Author: Petr Písař <ppisar at redhat.com>
Date:   Mon May 14 14:02:33 2012 +0200

    Count capturing parenthesis properly

 ...cessing-2-causes-the-interpreter-to-crash.patch |   93 ++++++++++++++++++++
 perl.spec                                          |   11 ++-
 2 files changed, 103 insertions(+), 1 deletions(-)
---
diff --git a/perl-5.12.4-Accessing-2-causes-the-interpreter-to-crash.patch b/perl-5.12.4-Accessing-2-causes-the-interpreter-to-crash.patch
new file mode 100644
index 0000000..0648a02
--- /dev/null
+++ b/perl-5.12.4-Accessing-2-causes-the-interpreter-to-crash.patch
@@ -0,0 +1,93 @@
+From 17d2206aa8868f59b80dbae247a146e423d28704 Mon Sep 17 00:00:00 2001
+From: Father Chrysostomos <sprout at cpan.org>
+Date: Fri, 25 Feb 2011 20:45:08 -0800
+Subject: [PATCH] Accessing $2 causes the interpreter to crash
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Petr Pisar: Ported to 5.12.4.
+
+Actually, it doesn’t. The original test case was:
+
+my $rx = qr'\$ (?| {(.+?)} | (.+?); | (.+?)(\s) )'x;
+my $test = '/home/$USERNAME ';
+die unless $test =~ $rx;
+print "1: $1\n";
+print "2: $2\n" if defined $2;
+
+This crashes even if I put an ‘exit’ right after the pattern match.
+
+What’s happening is that regcomp miscounts the number of capturing
+parenthesis pairs (cf. [perl #59734]), so the execution of the regular
+expression causes a buffer overflow which overwrites the op_sibling
+field of the regcreset op, causing a crash when the op is freed. (The
+exact failure may differ between builds, platforms, etc., of course.)
+
+S_reg in regcomp.c keeps a count of the parenthesised groups in a
+(?|...) construct, which it updates after each branch, if that branch
+has more captures than any previous branch. But it was not updating
+the count after the last branch.
+
+So this bug would occur if the last branch had more capturing paren-
+theses than any previous branch.
+
+Commit ee91d26, which fixed bug #59734, only solved the problem when
+there was just one branch (by updating the count before the loop that
+deals with subsequent branches was entered).
+
+This commit changes the code at the end of S_reg to take into account
+that RExC_npar (the current paren count) might have been increased by
+the last branch.
+
+Since the loop to deal with subsequent branches resets the count
+*before* each branch, the code that commit ee91d26 added is no longer
+necessary, so this commit removes it.
+---
+ regcomp.c     |    8 +-------
+ t/re/re_tests |    3 +++
+ 2 files changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/regcomp.c b/regcomp.c
+index 9652bbd..7b031fc 100644
+--- a/regcomp.c
++++ b/regcomp.c
+@@ -6163,12 +6163,6 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
+     parse_start = RExC_parse;   /* MJD */
+     br = regbranch(pRExC_state, &flags, 1,depth+1);
+ 
+-    if (freeze_paren) {
+-        if (RExC_npar > after_freeze)
+-            after_freeze = RExC_npar;
+-        RExC_npar = freeze_paren;
+-    }
+-
+     /*     branch_len = (paren != 0); */
+ 
+     if (br == NULL)
+@@ -6308,7 +6302,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
+ 	    FAIL("Junk on end of regexp");	/* "Can't happen". */
+ 	/* NOTREACHED */
+     }
+-    if (after_freeze)
++    if (after_freeze > RExC_npar)
+         RExC_npar = after_freeze;
+     return(ret);
+ }
+diff --git a/t/re/re_tests b/t/re/re_tests
+index 1807ffc..ce8db14 100644
+--- a/t/re/re_tests
++++ b/t/re/re_tests
+@@ -1326,6 +1326,9 @@ X(\w+)(?=\s)|X(\w+)	Xab	y	[$1-$2]	[-ab]
+ (?|(?<foo>x)|(?<bar>y))	x	y	$+{foo}	x
+ (?|(?<bar>y)|(?<foo>x))	x	y	$+{foo}	x
+ (?<bar>)(?|(?<foo>x))	x	y	$+{foo}	x
++# Used to crash, because the last branch was ignored when the parens
++# were counted:
++(?|(b)|()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(a))	a	y	$&	a
+ 
+ #Bug #41492
+ (?(DEFINE)(?<A>(?&B)+)(?<B>a))(?&A)	a	y	$&	a
+-- 
+1.7.7.6
+
diff --git a/perl.spec b/perl.spec
index a959dbc..178bcb6 100644
--- a/perl.spec
+++ b/perl.spec
@@ -20,7 +20,7 @@
 Name:           perl
 Version:        %{perl_version}
 # release number must be even higher, becase dual-lived modules will be broken otherwise
-Release:        165%{?dist}
+Release:        166%{?dist}
 Epoch:          %{perl_epoch}
 Summary:        Practical Extraction and Report Language
 Group:          Development/Languages
@@ -104,6 +104,10 @@ Patch16:        perl-5.14.2-Signal-handlers-must-run-before-sigsuspend-returns.p
 # Stop !$^V from leaking, rhbz#787613, RT#109762, fixed after 5.15.7.
 Patch17:        perl-5.12.4-Stop-V-from-leaking.patch
 
+# Count capturing parenthesis properly, rhbz#821405, RT#112874, fixed after
+# 5.13.10.
+Patch18:        perl-5.12.4-Accessing-2-causes-the-interpreter-to-crash.patch
+
 # Update some of the bundled modules
 # see http://fedoraproject.org/wiki/Perl/perl.spec for instructions
 
@@ -986,6 +990,7 @@ tarball from perl.org.
 %patch15 -p1
 %patch16 -p1
 %patch17 -p1
+%patch18 -p1
 
 #copy the example script
 cp -a %{SOURCE5} .
@@ -1208,6 +1213,7 @@ pushd %{build_archlib}/CORE/
     'Fedora Patch15: Fix leak with non-matching named captures' \
     'Fedora Patch16: Run signal handlers before returning from sigsuspend' \
     'Fedora Patch17: Stop !$^V from leaking' \
+    'Fedora Patch18: Count catpturing parenthesis properly' \
     %{nil}
 
 rm patchlevel.bak
@@ -1997,6 +2003,9 @@ rm -rf $RPM_BUILD_ROOT
 
 # Old changelog entries are preserved in CVS.
 %changelog
+* Mon May 14 2012 Petr Pisar <ppisar at redhat.com> - 4:5.12.4-166
+- Count capturing parenthesis properly (bug #821405)
+
 * Mon Feb 06 2012 Petr Pisar <ppisar at redhat.com> - 4:5.12.4-165
 - Run safe signal handlers before returning from sigsuspend() and pause()
   (bug #771228)


More information about the scm-commits mailing list