Test-CVE

 view release on metacpan or  search on metacpan

lib/Test/CVE.pm  view on Meta::CPAN

 $cve->skip ([qw( CVE-2011-0123 CVE-2020-1234 )]);

 $cve->want ("Foo::Bar", "4.321");
 $cve->want ("ExtUtils-MakeMaker");

 $cve->test;
 print $cve->report (width => $ENV{COLUMNS} || 80);
 my $csv = $cve->csv;

 has_no_cves (....);

=cut

use 5.014000;
use warnings;

our $VERSION = "0.11";

use version;
use Carp;
use HTTP::Tiny;
use Text::Wrap;
use JSON::MaybeXS;
use Module::CoreList;
use YAML::PP     ();
use List::Util qw( first uniq );
use base       qw( Test::Builder::Module );

use parent "Exporter";
our @EXPORT  = qw( has_no_cves );

# TODO:
# * NEW! https://fastapi.metacpan.org/cve/CPANSA-YAML-LibYAML-2012-1152
#        https://fastapi.metacpan.org/cve/release/YAML-1.20_001
# * Module::Install Makefile.PL's
#   use inc::Module::Install;
#   name            'Algorithm-Diff-XS';
#   license         'perl';
#   all_from        'lib/Algorithm/Diff/XS.pm';
# * Module::Build

sub new {
    my $class = shift;
    @_ % 2 and croak "Uneven number of arguments";
    my %self  = @_;
    $self{cpansa}   ||= "https://cpan-security.github.io/cpansa-feed/cpansa.json";
    $self{deps}     //= 1;
    $self{perl}     //= 1;
    $self{core}     //= 1;
    $self{minimum}  //= 0;
    $self{verbose}  //= 0;
    $self{width}    //= $ENV{COLUMNS} // 80;
    $self{want}     //= [];
    $self{cpanfile} ||= "cpanfile";
    $self{meta_jsn} ||= "META.json";
    $self{meta_yml} ||= "META.yml";
    $self{make_pl}  ||= "Makefile.PL";
    $self{build_pl} ||= "Build.PL";
    $self{CVE}        = {};
    ref $self{want} or $self{want} = [ $self{want} ]; # new->(want => "Foo")
    my $obj = bless \%self => $class;
    $obj->skip ($self{skip} // "CVE.SKIP");
    return $obj;
    } # new

sub skip {
    my $self = shift;
    if (@_) {
	if (my $skip = shift) {
	    if (ref $skip eq "HASH") {
		$self->{skip} = $skip;
		}
	    elsif (ref $skip eq "ARRAY") {
		$self->{skip} = { map { $_ => 1 } @$skip };
		}
	    elsif ($skip =~ m/^\x20-\xff]+$/ and open my $fh, "<", $skip) {
		my %s;
		while (<$fh>) {
		    s/[\s\r\n]+\z//;
		    m/^\s*(\w[-\w]+)(?:\s+(.*))?$/ or next;
		    $s{$1} = $2 // "";
		    }
		close $fh;
		$self->{skip} = { %s };
		}
	    else {
		$self->{skip} = {
		    map  { $_ => 1 }
		    grep { m/^\w[-\w]+$/ }
		    $skip, @_
		    };
		}
	    }
	else {
	    $self->{skip} = undef;
	    }
	}
    $self->{skip} ||= {};
    return [ sort keys %{$self->{skip}} ];
    } # skip

sub _read_cpansa {
    my $self = shift;
    my $src  = $self->{cpansa} or croak "No source for CVE database";
    $self->{verbose} and warn "Reading $src ...\n";

    # 'Compress-LZ4'   => [
    #   { affected_versions => [
    #       '<0.20'
    #       ],
    #     cpansa_id         => 'CPANSA-Compress-LZ4-2014-01',
    #     cves              => [],
    #     description       => 'Outdated LZ4 source code with security issue on 32bit systems.
    #
    #     references        => [
    #       'https://metacpan.org/changes/distribution/Compress-LZ4',
    #       'https://github.com/gray/compress-lz4/commit/fc503812b4cbba16429658e1dfe20ad8bbfd77a0'
    #       ],
    #     reported          => '2014-07-07',
    #     severity          => undef
    #     }



( run in 0.338 second using v1.01-cache-2.11-cpan-bf8d7bb2d05 )