Completed
Push — fix-125 ( ab9866...8be04f )
by Victor
13:16
created

Scanner::fwrite()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 23
rs 8.5906
cc 5
eloc 16
nc 6
nop 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
	public function getStatus(){
53
		if ($this->status instanceof Status){
54
			return $this->status;
55
		}
56
		return new Status();
57
	}
58
59
	/**
60
	 * Synchronous scan
61
	 * @param IScannable $item
62
	 * @return Status
63
	 */
64
	public function scan(IScannable $item) {
65
		$this->initScanner();
66
67
		while (false !== ($chunk = $item->fread())) {
68
			$this->writeChunk($chunk);
69
		}
70
		
71
		$this->shutdownScanner();
72
		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
	public function initScanner(){
96
		$this->byteCount = 0;
97
		$this->status = new Status();
98
	}
99
100
	/**
101
	 * @param string $chunk
102
	 */
103
	protected function writeChunk($chunk){
104
		$this->fwrite(
105
			$this->prepareChunk($chunk)
106
		);
107
	}
108
109
	/**
110
	 * @param string $data
111
	 */
112
	protected final function fwrite($data){
113
		$dataLength = strlen($data);
114
		if ($this->byteCount + $dataLength > $this->appConfig->getAvMaxFileSize()){
115
			$this->shutdownScanner();
116
			$this->initScanner();
117
		}
118
119
		$bytesWritten = @fwrite($this->getWriteHandle(), $data);
120
		if ($bytesWritten === false || $bytesWritten < $dataLength){
121
			if (!$this->isLogUsed) {
122
				$this->isLogUsed = true;
123
				\OC::$server->getLogger()->warning(
124
					'Failed to write a chunk. File is too big?',
125
					['app' => 'files_antivirus']
126
				);
127
			}
128
			// retry
129
			$this->initScanner();
130
			@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...
131
		} else {
132
			$this->byteCount += $bytesWritten;
133
		}
134
	}
135
136
	/**
137
	 * Get a resource to write data into
138
	 * @return resource
139
	 */
140
	protected function getWriteHandle(){
141
		return $this->writeHandle;
142
	}
143
144
	/**
145
	 * Prepare chunk (if required)
146
	 * @param string $data
147
	 * @return string
148
	 */
149
	protected function prepareChunk($data){
150
		return $data;
151
	}
152
}
153