Fix spurious "uninitialized value" warning in regex match
authorAaron Crane <arc@cpan.org>
Wed, 12 Sep 2012 15:04:38 +0000 (16:04 +0100)
committerKarl Williamson <public@khwilliamson.com>
Sat, 6 Oct 2012 16:13:42 +0000 (10:13 -0600)
The warning appeared if the pattern contains a floating substring for
which utf8 is needed, and the target string isn't in utf8.  In this
situation, downgrading the floating substring yields undef, which
triggers the warning.

Matching can't succeed in this situation, because it's impossible for
the non-utf8 target string to contain any string which needs utf8 for
its own representation.  So the warning is quelled by aborting the match
early.

Anchored substrings already have a check of this form; this commit makes
the corresponding change in the floating-substring case.

regexec.c
t/re/pat_advanced.t

index 989affa..350f293 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -2471,8 +2471,15 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, register char *stre
            STRLEN len;
            const char *little;
 
-           if (!(utf8_target ? prog->float_utf8 : prog->float_substr))
-               utf8_target ? to_utf8_substr(prog) : to_byte_substr(prog);
+           if (utf8_target && !prog->float_utf8)
+               to_utf8_substr(prog);
+           else if (!utf8_target && !prog->float_substr) {
+               to_byte_substr(prog);
+               if (prog->float_substr == &PL_sv_undef)
+                   /* downgrading failed, but target is not utf8, so
+                    * matching must fail */
+                   goto phooey;
+           }
            float_real = utf8_target ? prog->float_utf8 : prog->float_substr;
 
             little = SvPV_const(float_real, len);
index 05cc191..9502928 100644 (file)
@@ -789,6 +789,12 @@ sub run_tests {
     }
 
     {
+        # The second half of RT #114808
+        warning_is(sub {'aa' =~ /.+\x{100}/}, undef,
+                   'utf8-only floating substr, non-utf8 target, no warning');
+    }
+
+    {
         my $message = "qr /.../x";
         my $R = qr / A B C # D E/x;
         ok("ABCDE" =~    $R   && $& eq "ABC", $message);