File Coverage

lib/File/Information/VerifyTestResult.pm
Criterion Covered Total %
statement 17 56 30.3
branch 0 30 0.0
condition 0 30 0.0
subroutine 6 12 50.0
pod n/a
total 23 128 17.9


line stmt bran cond sub pod time code
1             # Copyright (c) 2024-2025 Philipp Schafft <lion@cpan.org>
2              
3             # licensed under Artistic License 2.0 (see LICENSE file)
4              
5             # ABSTRACT: generic module for extracting information from filesystems
6              
7              
8             package File::Information::VerifyTestResult;
9              
10 1     1   16 use v5.10;
  1         5  
11 1     1   5 use strict;
  1         3  
  1         42  
12 1     1   6 use warnings;
  1         2  
  1         59  
13              
14 1     1   5 use parent 'File::Information::VerifyBase';
  1         3  
  1         7  
15              
16 1     1   89 use Carp;
  1         1  
  1         148  
17              
18             our $VERSION = v0.16;
19              
20             use constant {
21 1         1305 CLASS_METADATA => 'meatdata',
22             CLASS_WEAK => 'weak',
23             CLASS_STRONG => 'strong',
24 1     1   6 };
  1         2  
25              
26             my %supported_tests = (
27             (map {
28             'get_'.$_ => {
29             class => CLASS_METADATA,
30             cb => \&_test_get,
31             key => $_,
32             },
33             } qw(size mediatype)),
34             (map {
35             'digest_'.($_ =~ tr/-/_/r) => {
36             class => CLASS_STRONG,
37             cb => \&_test_digest,
38             digest => $_,
39             },
40             } grep {$_ ne 'sha-2-512'} map {'sha-2-'.$_, 'sha-3-'.$_} qw(224 256 384 512)), # all of SHA-2 and SHA-3 but SHA-2-512
41             (map {
42             'digest_'.($_ =~ tr/-/_/r) => {
43             class => CLASS_WEAK,
44             cb => \&_test_digest,
45             digest => $_,
46             },
47             } qw(md-4-128 md-5-128 sha-1-160 ripemd-1-160 tiger-1-192 tiger-2-192)), # all the others basically
48             inode => {
49             class => CLASS_STRONG,
50             cb => \&_test_inode,
51             },
52             );
53              
54             # ----------------
55              
56             sub _new {
57 0     0     my ($pkg, %opts) = @_;
58 0           my $self = $pkg->SUPER::_new(%opts);
59 0   0       my $test = $supported_tests{$opts{test}} // croak 'Unsupported test';
60 0           my $res;
61              
62 0   0       $self->{status} = $res = eval {$test->{cb}->($self, $test)} // $pkg->STATUS_ERROR;
  0            
63              
64 0 0 0       if (ref($res) && $res->isa('File::Information::VerifyBase')) {
65 0           return $res;
66             }
67              
68 0 0 0       if (defined(my $digest = $test->{digest}) && $test->{class} eq CLASS_STRONG) {
69 0           my $info = $self->instance->digest_info($digest);
70 0 0         $self->{class} = CLASS_WEAK if $info->{unsafe};
71             }
72              
73 0           return $self;
74             }
75              
76             sub _supported_tests {
77 0     0     return keys %supported_tests;
78             }
79              
80             sub _class {
81 0     0     my ($self) = @_;
82 0   0       return $self->{class} // $supported_tests{$self->{test}}{class};
83             }
84              
85             sub _test_get {
86 0     0     my ($self, $test) = @_;
87 0           my $key = $test->{key};
88 0           my $from = $self->base_from->get($key, lifecycle => $self->{lifecycle_from}, default => undef, as => 'Data::Identifier');
89 0           my $to = $self->base_to->get($key, lifecycle => $self->{lifecycle_to}, default => undef, as => 'Data::Identifier');
90              
91 0 0 0       if (defined($from) && defined($to)) {
92             #warn sprintf('key=<%s>, %s -> %s: from=<%s>, to=<%s>', $test->{key}, $self->{lifecycle_from}, $self->{lifecycle_to}, $from // '', $to // '') if $key eq 'mediatype';
93 0 0         return $self->STATUS_PASSED if $from->eq($to);
94             }
95              
96 0           $from = $self->base_from->get($key, lifecycle => $self->{lifecycle_from}, default => undef, as => 'raw');
97 0           $to = $self->base_to->get($key, lifecycle => $self->{lifecycle_to}, default => undef, as => 'raw');
98              
99             #warn sprintf('key=<%s>, %s -> %s: from=<%s>, to=<%s>', $test->{key}, $self->{lifecycle_from}, $self->{lifecycle_to}, $from // '', $to // '') if $key eq 'mediatype';
100              
101 0 0 0       return $self->STATUS_NO_DATA unless defined($from) && defined($to);
102 0 0         return $from eq $to ? $self->STATUS_PASSED : $self->STATUS_FAILED;
103             }
104              
105             sub _test_digest {
106 0     0     my ($self, $test) = @_;
107 0           my $from = $self->base_from->digest($test->{digest}, lifecycle => $self->{lifecycle_from}, default => undef, as => 'hex');
108 0           my $to = $self->base_to->digest($test->{digest}, lifecycle => $self->{lifecycle_to}, default => undef, as => 'hex');
109              
110 0 0 0       return $self->STATUS_NO_DATA unless defined($from) && defined($to);
111             #warn sprintf('key=<%s>, %s -> %s: from=<%s>, to=<%s>', $test->{digest}, $self->{lifecycle_from}, $self->{lifecycle_to}, $from // '', $to // '');
112 0 0         return $from eq $to ? $self->STATUS_PASSED : $self->STATUS_FAILED;
113             }
114              
115             sub _test_inode {
116 0     0     my ($self, $test) = @_;
117 0           my $base_from = $self->base_from;
118 0           my $base_to = $self->base_to;
119 0 0         my $inode_from = $base_from->can('inode') ? $base_from->inode : $base_from->isa('File::Information::Remote') ? $base_from : undef;
    0          
120 0 0         my $inode_to = $base_to->can('inode') ? $base_to->inode : $base_to->isa('File::Information::Remote') ? $base_to : undef;
    0          
121              
122 0 0 0       if (defined($inode_from) && defined($inode_to)) {
123 0 0 0       if ($base_from != $inode_from || $base_to != $inode_to) {
124 0           return $inode_from->verify(lifecycle_from => $self->{lifecycle_from}, lifecycle_to => $self->{lifecycle_to}, base_to => $inode_to);
125             }
126             }
127 0           return $self->STATUS_NO_DATA;
128             }
129              
130             1;
131              
132             __END__
133              
134             =pod
135              
136             =encoding UTF-8
137              
138             =head1 NAME
139              
140             File::Information::VerifyTestResult - generic module for extracting information from filesystems
141              
142             =head1 VERSION
143              
144             version v0.16
145              
146             =head1 SYNOPSIS
147              
148             use File::Information;
149              
150             my File::Information::Inode $inode = ...;
151              
152             my File::Information::VerifyResult $result = $inode->verify;
153              
154             my $passed = $base->has_passed;
155              
156             This package inherits from L<File::Information::VerifyBase>.
157              
158             =head1 METHODS
159              
160             =head1 AUTHOR
161              
162             Philipp Schafft <lion@cpan.org>
163              
164             =head1 COPYRIGHT AND LICENSE
165              
166             This software is Copyright (c) 2024-2025 by Philipp Schafft <lion@cpan.org>.
167              
168             This is free software, licensed under:
169              
170             The Artistic License 2.0 (GPL Compatible)
171              
172             =cut