Completed
Pull Request — master (#32)
by Krishnaprasad
04:43
created

ClamavValidator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 3
cts 3
cp 1
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 5
crap 1
1
<?php namespace Sunspikes\ClamavValidator;
2
3
use Illuminate\Contracts\Translation\Translator;
4
use Illuminate\Support\Arr;
5
use Illuminate\Support\Facades\Config;
6
use Illuminate\Validation\Validator;
7
use Xenolope\Quahog\Client as QuahogClient;
8
use Socket\Raw\Factory as SocketFactory;
9
use Symfony\Component\HttpFoundation\File\UploadedFile;
10
11
class ClamavValidator extends Validator
12
{
13
    /**
14
     * Creates a new instance of ClamavValidator.
15
     *
16
     * ClamavValidator constructor.
17
     * @param Translator $translator
18
     * @param array      $data
19
     * @param array      $rules
20
     * @param array      $messages
21
     * @param array      $customAttributes
22
     */
23 4
    public function __construct(
24
        Translator $translator,
25
        array $data,
26
        array $rules,
27
        array $messages = [],
28
        array $customAttributes = []
29
    ) {
30 4
        parent::__construct($translator, $data, $rules, $messages, $customAttributes);
31 4
    }
32
33
    /**
34
     * Validate the uploaded file for virus/malware with ClamAV.
35
     *
36
     * @param  $attribute   string
37
     * @param  $value       mixed
38
     * @param  $parameters  array
39
     *
40
     * @return boolean
41
     * @throws ClamavValidatorException
42
     */
43 3
    public function validateClamav($attribute, $value, $parameters)
0 ignored issues
show
Unused Code introduced by
The parameter $attribute is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $parameters is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
44
    {
45 3
        if (true === Config::get('clamav.skip_validation')) {
46
            return true;
47
        }
48
49 3
        $file = $this->getFilePath($value);
50 3
        if (! is_readable($file)) {
51 1
            throw ClamavValidatorException::forNonReadableFile($file);
52
        }
53
54
        try {
55 2
            $socket  = $this->getClamavSocket();
56 2
            $scanner = $this->createQuahogScannerClient($socket);
57 2
            $result  = $scanner->scanResourceStream(fopen($file, 'rb'));
58 2
        } catch (\Exception $exception) {
59
            throw ClamavValidatorException::forClientException($exception);
0 ignored issues
show
Documentation introduced by
$exception is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
60
        }
61
62 2
        if (QuahogClient::RESULT_ERROR === $result['status']) {
63
            throw ClamavValidatorException::forScanResult($result);
64
        }
65
66
        // Check if scan result is clean
67 2
        return QuahogClient::RESULT_OK === $result['status'];
68
    }
69
70
    /**
71
     * Guess the ClamAV socket.
72
     *
73
     * @return string
74
     */
75 2
    protected function getClamavSocket()
76
    {
77 2
        $preferredSocket = Config::get('clamav.preferred_socket');
78
79 2
        if ($preferredSocket === 'unix_socket') {
80 2
            $unixSocket = Config::get('clamav.unix_socket');
81 2
            if (file_exists($unixSocket)) {
82 2
                return 'unix://' . $unixSocket;
83
            }
84
        }
85
        // We use the tcp_socket as fallback as well
86
        return Config::get('clamav.tcp_socket');
87
    }
88
89
    /**
90
     * Return the file path from the passed object.
91
     *
92
     * @param string|array|UploadedFile $file
93
     * @return string
94
     */
95 3
    protected function getFilePath($file)
96
    {
97
        // if were passed an instance of UploadedFile, return the path
98 3
        if ($file instanceof UploadedFile) {
99
            return $file->getPathname();
100
        }
101
102
        // if we're passed a PHP file upload array, return the "tmp_name"
103 3
        if (is_array($file) && null !== Arr::get($file, 'tmp_name')) {
104
            return $file['tmp_name'];
105
        }
106
107
        // fallback: we were likely passed a path already
108 3
        return $file;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $file; of type string|array is incompatible with the return type documented by Sunspikes\ClamavValidato...vValidator::getFilePath of type string as it can also be of type array which is not included in this return type.
Loading history...
109
    }
110
111
    /**
112
     * Create a new quahog ClamAV scanner client.
113
     *
114
     * @param string $socket
115
     * @return QuahogClient
116
     */
117 2
    protected function createQuahogScannerClient($socket)
118
    {
119
        // Create a new client socket instance
120 2
        $client = (new SocketFactory())->createClient($socket);
121
122 2
        return new QuahogClient($client, Config::get('clamav.socket_read_timeout'), PHP_NORMAL_READ);
123
    }
124
}
125