File Coverage

blib/lib/File/VirusScan/Engine/Command/NAI/Uvscan.pm
Criterion Covered Total %
statement 25 65 38.4
branch 1 30 3.3
condition n/a
subroutine 9 9 100.0
pod 1 2 50.0
total 36 106 33.9


line stmt bran cond sub pod time code
1             package File::VirusScan::Engine::Command::NAI::Uvscan;
2 1     1   54006 use strict;
  1         2  
  1         35  
3 1     1   5 use warnings;
  1         1  
  1         30  
4 1     1   4 use Carp;
  1         1  
  1         103  
5              
6 1     1   380 use File::VirusScan::Engine::Command;
  1         2  
  1         5  
7 1     1   35 use vars qw( @ISA );
  1         2  
  1         34  
8             @ISA = qw( File::VirusScan::Engine::Command );
9              
10 1     1   3 use Cwd 'abs_path';
  1         0  
  1         34  
11              
12 1     1   302 use File::VirusScan::Result;
  1         1  
  1         326  
13              
14             sub default_arguments
15             {
16 6     6 0 26 return [ qw( --mime --noboot --secure --allole ) ];
17             }
18              
19             sub scan
20             {
21 1     1 1 829 my ($self, $path) = @_;
22              
23 1 50       35 if(abs_path($path) ne $path) {
24 1         11 return File::VirusScan::Result->error("Path $path is not absolute");
25             }
26              
27 0           my ($exitcode, $scan_response) = eval { $self->_run_commandline_scanner(join(' ', $self->{command}, @{ $self->{args} }, $path, '2>&1'), qr/Found/,); };
  0            
  0            
28              
29 0 0         if($@) {
30 0           return File::VirusScan::Result->error($@);
31             }
32              
33 0 0         if(0 == $exitcode) {
34 0           return File::VirusScan::Result->clean();
35             }
36              
37 0 0         if(2 == $exitcode) {
38 0           return File::VirusScan::Result->error('Driver integrity check failed');
39             }
40              
41 0 0         if(6 == $exitcode) {
42              
43             # "A general problem occurred" -- idiot Windoze
44             # programmers... nothing else to do but pass it on
45 0           return File::VirusScan::Result->error('General problem occurred');
46             }
47              
48 0 0         if(8 == $exitcode) {
49 0           return File::VirusScan::Result->error('Could not find a driver');
50             }
51              
52 0 0         if(12 == $exitcode) {
53 0           return File::VirusScan::Result->error('Scanner tried to clean file, but failed');
54             }
55              
56 0 0         if(13 == $exitcode) {
57              
58             # Finally, the virus-hit case
59             #
60             # TODO: what if more than one virus found?
61             # TODO: can/should we capture infected filenames?
62              
63             # Sigh... stupid NAI can't have a standard message. Go
64             # through hoops to get virus name.
65 0           $scan_response =~ s/ !+//;
66 0           $scan_response =~ s/!+//;
67              
68 0           my $virus_name = '';
69              
70 0           for ($scan_response) {
71 0 0         m/Found: EICAR test file/i && do {
72 0           $virus_name = 'EICAR-Test';
73 0           last;
74             };
75 0 0         m/^\s+Found the (\S+) .*virus/i && do {
76 0           $virus_name = $1;
77 0           last;
78             };
79 0 0         m/Found the (.*) trojan/i && do {
80 0           $virus_name = $1;
81 0           last;
82             };
83 0 0         m/Found .* or variant (.*)/i && do {
84 0           $virus_name = $1;
85 0           last;
86             };
87             }
88              
89 0 0         if($virus_name eq '') {
90 0           $virus_name = 'unknown-NAI-virus';
91             }
92              
93 0           return File::VirusScan::Result->virus($virus_name);
94             }
95              
96 0 0         if(19 == $exitcode) {
97 0           return File::VirusScan::Result->error('Self-check failed');
98             }
99              
100 0 0         if(102 == $exitcode) {
101 0           return File::VirusScan::Result->error('User quit using --exit-on-error');
102             }
103              
104 0           return File::VirusScan::Result->error("Unknown return code from uvscan: $exitcode");
105             }
106              
107             1;
108             __END__