S_save_lines() was using strchr() when it should have been using
Nicholas Clark [Mon, 17 Nov 2008 22:54:17 +0000 (22:54 +0000)]
memchr(). Result - eval""ed source with embedded NULs was not split
correctly into lines for the debugger. Obscure. But still a bug.
Maybe the Campaign for the Elimination of strlen() needs to take a long
hard stare at every strchr() too. And strmp() while we're looking.

p4raw-id: //depot/perl@34876

pp_ctl.c
t/comp/retainedlines.t

index cd5c1c1..ba0dee0 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2764,7 +2764,7 @@ S_save_lines(pTHX_ AV *array, SV *sv)
        const char *t;
        SV * const tmpstr = newSV_type(SVt_PVMG);
 
-       t = strchr(s, '\n');
+       t = (const char *)memchr(s, '\n', send - s);
        if (t)
            t++;
        else
index 2148fc5..aa044ad 100644 (file)
@@ -10,16 +10,19 @@ BEGIN {
 
 use strict;
 
-plan( tests => 10 );
+plan( tests => 19 );
 
 my @before = grep { /eval/ } keys %::;
 
 is (@before, 0, "No evals");
 
-for my $sep (' ') {
+my %seen;
+my $name = 'foo';
+
+for my $sep (' ', "\0") {
     $^P = 0xA;
 
-    my $prog = "sub foo {
+    my $prog = "sub $name {
     'Perl${sep}Rules'
 };
 1;
@@ -29,9 +32,9 @@ for my $sep (' ') {
     # Is there a more efficient way to write this?
     my @expect_lines = (undef, map ({"$_\n"} split "\n", $prog), "\n", ';');
 
-    my @keys = grep { /eval/ } keys %::;
+    my @keys = grep {!$seen{$_}} grep { /eval/ } keys %::;
 
-    is (@keys, 1, "1 eval");
+    is (@keys, 1, "1 new eval");
 
     my @got_lines = @{$::{$keys[0]}};
 
@@ -40,4 +43,6 @@ for my $sep (' ') {
     for (0..$#expect_lines) {
        is ($got_lines[$_], $expect_lines[$_], "Line $_ is correct");
     }
+    $seen{$keys[0]}++;
+    $name++;
 }