1 | <?php |
||||
2 | |||||
3 | /* |
||||
4 | * @copyright 2015 Mautic Contributors. All rights reserved |
||||
5 | * @author Mautic |
||||
6 | * |
||||
7 | * @link http://mautic.org |
||||
8 | * |
||||
9 | * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html |
||||
10 | */ |
||||
11 | |||||
12 | namespace Mautic\CoreBundle\IpLookup; |
||||
13 | |||||
14 | use Joomla\Http\HttpFactory; |
||||
15 | use Mautic\CoreBundle\Form\Type\IpLookupDownloadDataStoreButtonType; |
||||
16 | use PharData; |
||||
17 | use PharFileInfo; |
||||
18 | use RecursiveIteratorIterator; |
||||
19 | |||||
20 | /** |
||||
21 | * Class AbstractLocalDataLookup. |
||||
22 | */ |
||||
23 | abstract class AbstractLocalDataLookup extends AbstractLookup implements IpLookupFormInterface |
||||
24 | { |
||||
25 | /** |
||||
26 | * @const TAR_CACHE_FOLDER |
||||
27 | */ |
||||
28 | const TAR_CACHE_FOLDER = 'unpack'; |
||||
29 | |||||
30 | /** |
||||
31 | * @const TAR_TEMP_FILE |
||||
32 | */ |
||||
33 | const TAR_TEMP_FILE = 'temp.tar.gz'; |
||||
34 | |||||
35 | /** |
||||
36 | * Path to the local data store. |
||||
37 | * |
||||
38 | * @return string |
||||
39 | */ |
||||
40 | abstract public function getLocalDataStoreFilepath(); |
||||
41 | |||||
42 | /** |
||||
43 | * Return the URL to manually download. |
||||
44 | * |
||||
45 | * @return string |
||||
46 | */ |
||||
47 | abstract public function getRemoteDateStoreDownloadUrl(); |
||||
48 | |||||
49 | /** |
||||
50 | * @return string |
||||
51 | */ |
||||
52 | public function getConfigFormService() |
||||
53 | { |
||||
54 | return IpLookupDownloadDataStoreButtonType::class; |
||||
55 | } |
||||
56 | |||||
57 | /** |
||||
58 | * {@inheritdoc} |
||||
59 | * |
||||
60 | * @return array |
||||
61 | */ |
||||
62 | public function getConfigFormThemes() |
||||
63 | { |
||||
64 | return []; |
||||
65 | } |
||||
66 | |||||
67 | /** |
||||
68 | * Download remote data store. |
||||
69 | * |
||||
70 | * Used by the mautic:iplookup:update_data command and form fetch button (if applicable) to update local IP data stores |
||||
71 | * |
||||
72 | * @return bool |
||||
73 | */ |
||||
74 | public function downloadRemoteDataStore() |
||||
75 | { |
||||
76 | $connector = HttpFactory::getHttp(); |
||||
77 | $package = $this->getRemoteDateStoreDownloadUrl(); |
||||
78 | |||||
79 | try { |
||||
80 | $data = $connector->get($package); |
||||
81 | } catch (\Exception $exception) { |
||||
82 | $this->logger->error('Failed to fetch remote IP data: '.$exception->getMessage()); |
||||
83 | } |
||||
84 | |||||
85 | $tempTarget = $this->cacheDir.'/'.basename($package); |
||||
86 | $tempExt = strtolower(pathinfo($package, PATHINFO_EXTENSION)); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
87 | $localTarget = $this->getLocalDataStoreFilepath(); |
||||
88 | $localTargetExt = strtolower(pathinfo($localTarget, PATHINFO_EXTENSION)); |
||||
89 | |||||
90 | try { |
||||
91 | $success = false; |
||||
92 | |||||
93 | switch (true) { |
||||
94 | case $localTargetExt === $tempExt: |
||||
95 | $success = (bool) file_put_contents($localTarget, $data->body); |
||||
96 | |||||
97 | break; |
||||
98 | |||||
99 | case $this->endsWith($package, 'tar.gz'): |
||||
0 ignored issues
–
show
$this->endsWith($package, 'tar.gz') is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last
Loading history...
|
|||||
100 | /** |
||||
101 | * If tar.gz it loops whole folder structure and copy the file which has the same basename as |
||||
102 | * desired localTarget. |
||||
103 | */ |
||||
104 | $tempTargetFolder = $this->cacheDir.'/'.self::TAR_CACHE_FOLDER; |
||||
105 | $temporaryPhar = $tempTargetFolder.'/'.self::TAR_TEMP_FILE; |
||||
106 | if (!is_dir($tempTargetFolder)) { |
||||
107 | // dir doesn't exist, make it |
||||
108 | mkdir($tempTargetFolder); |
||||
109 | } |
||||
110 | file_put_contents($temporaryPhar, $data->body); |
||||
111 | $pharData = new PharData($temporaryPhar); |
||||
112 | foreach (new RecursiveIteratorIterator($pharData) as $file) { |
||||
113 | /** @var PharFileInfo $file */ |
||||
114 | if ($file->getBasename() === basename($localTarget)) { |
||||
115 | $success = copy($file->getPathname(), $localTarget); |
||||
116 | } |
||||
117 | } |
||||
118 | @unlink($temporaryPhar); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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...
|
|||||
119 | |||||
120 | break; |
||||
121 | |||||
122 | case 'gz' == $tempExt: |
||||
123 | $memLimit = $this->sizeInByte(ini_get('memory_limit')); |
||||
124 | $freeMem = $memLimit - memory_get_peak_usage(); |
||||
125 | //check whether there is enough memory to handle large iplookp DB |
||||
126 | // or will throw iplookup exception |
||||
127 | if (function_exists('gzdecode') && strlen($data->body) < ($freeMem / 3)) { |
||||
128 | $success = (bool) file_put_contents($localTarget, gzdecode($data->body)); |
||||
129 | } elseif (function_exists('gzopen')) { |
||||
130 | if (file_put_contents($tempTarget, $data->body)) { |
||||
131 | $bufferSize = 4096; // read 4kb at a time |
||||
132 | $file = gzopen($tempTarget, 'rb'); |
||||
133 | $outFile = fopen($localTarget, 'wb'); |
||||
134 | while (!gzeof($file)) { |
||||
135 | fwrite($outFile, gzread($file, $bufferSize)); |
||||
136 | } |
||||
137 | fclose($outFile); |
||||
138 | gzclose($file); |
||||
139 | @unlink($tempTarget); |
||||
140 | $success = true; |
||||
141 | } |
||||
142 | } |
||||
143 | |||||
144 | break; |
||||
145 | |||||
146 | case 'zip' == $tempExt: |
||||
147 | file_put_contents($tempTarget, $data->body); |
||||
148 | |||||
149 | $zipper = new \ZipArchive(); |
||||
150 | |||||
151 | $zipper->open($tempTarget); |
||||
152 | $success = $zipper->extractTo($localTarget); |
||||
153 | $zipper->close(); |
||||
154 | @unlink($tempTarget); |
||||
155 | break; |
||||
156 | } |
||||
157 | } catch (\Exception $exception) { |
||||
158 | error_log($exception); |
||||
159 | |||||
160 | $success = false; |
||||
161 | } |
||||
162 | |||||
163 | return $success; |
||||
164 | } |
||||
165 | |||||
166 | /** |
||||
167 | * Get the common directory for data. |
||||
168 | * |
||||
169 | * @return string|null |
||||
170 | */ |
||||
171 | protected function getDataDir() |
||||
172 | { |
||||
173 | if (null !== $this->cacheDir) { |
||||
174 | if (!file_exists($this->cacheDir)) { |
||||
175 | mkdir($this->cacheDir); |
||||
176 | } |
||||
177 | |||||
178 | $dataDir = $this->cacheDir.'/../ip_data'; |
||||
179 | |||||
180 | if (!file_exists($dataDir)) { |
||||
181 | mkdir($dataDir); |
||||
182 | } |
||||
183 | |||||
184 | return $dataDir; |
||||
185 | } |
||||
186 | |||||
187 | return null; |
||||
188 | } |
||||
189 | |||||
190 | protected function sizeInByte($size) |
||||
191 | { |
||||
192 | $data = (int) substr($size, 0, -1); |
||||
193 | switch (strtoupper(substr($size, -1))) { |
||||
194 | case 'K': |
||||
195 | return $data * 1024; |
||||
196 | case 'M': |
||||
197 | return $data * 1024 * 1024; |
||||
198 | case 'G': |
||||
199 | return $data * 1024 * 1024 * 1024; |
||||
200 | } |
||||
201 | } |
||||
202 | |||||
203 | /** |
||||
204 | * Get if the string ends with. |
||||
205 | * |
||||
206 | * @param string $haystack |
||||
207 | * @param string $needle |
||||
208 | * |
||||
209 | * @return bool |
||||
210 | */ |
||||
211 | private function endsWith($haystack, $needle) |
||||
212 | { |
||||
213 | return 0 === substr_compare($haystack, $needle, -strlen($needle)); |
||||
214 | } |
||||
215 | } |
||||
216 |