stop ""-overloaded Regex recursing
authorDavid Mitchell <davem@iabyn.com>
Wed, 12 Sep 2012 11:36:08 +0000 (12:36 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 12 Sep 2012 11:36:08 +0000 (12:36 +0100)
There was code to detect this, but it checked for the returned value being
the same as before, but in this case it was returning a *new* temporary
reference to the same Regexp object; so check for that too.

lib/overload.t
regcomp.c

index 597c1f7..afbe999 100644 (file)
@@ -48,7 +48,7 @@ package main;
 
 $| = 1;
 BEGIN { require './test.pl' }
-plan tests => 5190;
+plan tests => 5191;
 
 use Scalar::Util qw(tainted);
 
@@ -2669,6 +2669,24 @@ is eval {"$a"}, overload::StrVal($a), 'fallback is stored under "()"';
     }
 }
 
+{
+    # Making Regexp class overloaded: avoid infinite recursion.
+    # Do this in a separate process since it, well, overloads Regexp!
+    fresh_perl_is(
+       <<'EOF',
+package Regexp;
+use overload q{""} => sub {$_[0] };
+package main;
+my $r1 = qr/1/;
+my $r2 = qr/ABC$r1/;
+print $r2,"\n";
+EOF
+       '(?^:ABC(?^:1))',
+       { stderr => 1 },
+       'overloaded REGEXP'
+    );
+}
+
 { # undefining the overload stash -- KEEP THIS TEST LAST
     package ant;
     use overload '+' => 'onion';
index 7f60e29..6edfb1c 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -5501,8 +5501,11 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
                else  {
                     while (SvAMAGIC(msv)
                             && (sv = AMG_CALLunary(msv, string_amg))
-                            && sv != msv)
-                    {
+                            && sv != msv
+                            &&  !(   SvROK(msv)
+                                  && SvROK(sv)
+                                  && SvRV(msv) == SvRV(sv))
+                    ) {
                         msv = sv;
                         SvGETMAGIC(msv);
                     }