Completed
Pull Request — stable8.2 (#145)
by Victor
02:36
created

Scanner::writeChunk()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
* ownCloud - files_antivirus
5
*
6
* @author Manuel Deglado
7
* @copyright 2012 Manuel Deglado [email protected]
8
*
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
11
* License as published by the Free Software Foundation; either
12
* version 3 of the License, or any later version.
13
*
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
18
*
19
* You should have received a copy of the GNU Affero General Public
20
* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
21
*
22
*/
23
24
namespace OCA\Files_Antivirus;
25
26
abstract class Scanner {
27
	
28
	/**
29
	 * Scan result
30
	 * @var \OCA\Files_Antivirus\Status
31
	 */
32
	protected $status;
33
34
	/** @var  int */
35
	protected $byteCount;
36
37
	/** @var  resource */
38
	protected $writeHandle;
39
40
	/** @var \OCA\Files_Antivirus\AppConfig */
41
	protected $appConfig;
42
43
	/** @var bool */
44
	protected $isLogUsed;
45
46
	/**
47
	 * Close used resources
48
	 */
49
	abstract protected function shutdownScanner();
50
51
52 3
	public function getStatus(){
53 3
		if ($this->status instanceof Status){
54 3
			return $this->status;
55
		}
56
		return new Status();
57
	}
58
59
	/**
60
	 * Synchronous scan
61
	 * @param IScannable $item
62
	 * @return Status
63
	 */
64 3
	public function scan(IScannable $item) {
65 3
		$this->initScanner();
66
67 3
		while (false !== ($chunk = $item->fread())) {
68 3
			$this->writeChunk($chunk);
69 3
		}
70
		
71 3
		$this->shutdownScanner();
72 3
		return $this->getStatus();
73
	}
74
	
75
	/**
76
	 * Async scan - new portion of data is available
77
	 * @param string $data
78
	 */
79
	public function onAsyncData($data){
80
		$this->writeChunk($data);
81
	}
82
	
83
	/**
84
	 * Async scan - resource is closed
85
	 * @return Status
86
	 */
87
	public function completeAsyncScan(){
88
		$this->shutdownScanner();
89
		return $this->getStatus();
90
	}
91
	
92
	/**
93
	 * Open write handle. etc
94
	 */
95 3
	public function initScanner(){
96 3
		$this->byteCount = 0;
97 3
		$this->status = new Status();
98 3
	}
99
100
	/**
101
	 * @param string $chunk
102
	 */
103 3
	protected function writeChunk($chunk){
104 3
		$this->fwrite(
105 3
			$this->prepareChunk($chunk)
106 3
		);
107 3
	}
108
109
	/**
110
	 * @param string $data
111
	 */
112 3
	protected final function fwrite($data){
113 3
		$dataLength = strlen($data);
114 3
		$fileSizeLimit = intval($this->appConfig->getAvMaxFileSize());
115 3
		if ($fileSizeLimit !== -1 && $this->byteCount + $dataLength > $fileSizeLimit){
116 3
			$this->shutdownScanner();
117 3
			$this->initScanner();
118 3
		}
119
120 3
		$bytesWritten = @fwrite($this->getWriteHandle(), $data);
121 3
		if ($bytesWritten === false || $bytesWritten < $dataLength){
122
			if (!$this->isLogUsed) {
123
				$this->isLogUsed = true;
124
				\OC::$server->getLogger()->warning(
125
					'Failed to write a chunk. File is too big?',
126
					['app' => 'files_antivirus']
127
				);
128
			}
129
			// retry
130
			$this->initScanner();
131
			@fwrite($this->getWriteHandle(), $data);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
132
		} else {
133 3
			$this->byteCount += $bytesWritten;
134
		}
135 3
	}
136
137
	/**
138
	 * Get a resource to write data into
139
	 * @return resource
140
	 */
141 3
	protected function getWriteHandle(){
142 3
		return $this->writeHandle;
143
	}
144
145
	/**
146
	 * Prepare chunk (if required)
147
	 * @param string $data
148
	 * @return string
149
	 */
150 3
	protected function prepareChunk($data){
151 3
		return $data;
152
	}
153
}
154