p5pclub / devel-quickcover

Quick & dirty code coverage for Perl
Other
7 stars 5 forks source link

Devel::QuickCover segfaults if a function resulting from a typeglob alias is called after the original is undefined #20

Open sloanebernstein opened 5 years ago

sloanebernstein commented 5 years ago

(Reposted from https://rt.cpan.org/Public/Bug/Display.html?id=130307)

If a function is given a typeglob alias by assigning a reference of that function to the typeglob, then the original symbol is undefined, Perl will segfault inside of Devel::QuickCover as a result of a null pointer when the function is invoked as its alias. Specifically, consider the following program:

# cat bad.pl
sub a { 0; }
sub b { 1; }
*a = \&b;

my ( $a_ref, $b_ref ) = ( \&a, \&b );
print "$a_ref, $b_ref\n";

undef *b if $ARGV[1];
$a_ref = \&a;
print "$a_ref\n";

my $i = a();
print "$i\n”;

The expected result of the program under all cases is that $i will be assigned the value 1. However, if Devel::QuickCover is included when an argument is passed (which causes the original &b to become undefined), Perl will segfault:

[root@sandbox ~]# perl bad.pl --
CODE(0xdeecd0), CODE(0xdeecd0)
CODE(0xdeecd0)
1

[root@sandbox ~]# perl bad.pl -- undefine
CODE(0x1dfac98), CODE(0x1dfac98)
CODE(0x1dfac98)
1

[root@sandbox ~]# perl -MDevel::QuickCover bad.pl --
CODE(0x1976ce0), CODE(0x1976ce0)
CODE(0x1976ce0)
1

[root@sandbox ~]# perl -MDevel::QuickCover bad.pl -- undefine
CODE(0x2276cc8), CODE(0x2276cc8)
CODE(0x2276cc8)
Segmentation fault

The immediate cause of the segfault is that the file variable is NULL when add_covered_sub_helper() in quickcover.xs is called:

static void add_covered_sub_helper(pTHX_ CoverList* cover, const char* file, const char* name, U32 line, int phase) {
    U32 file_hash, name_hash;

    PERL_HASH(file_hash, file, strlen(file));
    PERL_HASH(name_hash, name, strlen(name));
    cover_sub_add_covered_sub(cover, file, file_hash, name, name_hash, line, phase);
}

I have reproduced this with a custom build of Perl 5.28.0 and Devel::QuickCover 0.900010 on CentOS 7.6, as well as the system build of Perl 5.22.2 and CPAN build of Devel::QuickCover 0.900014 on Slackware 14.2.