This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Asset Packagist. |
||
4 | * |
||
5 | * @link https://github.com/hiqdev/asset-packagist |
||
6 | * @package asset-packagist |
||
7 | * @license BSD-3-Clause |
||
8 | * @copyright Copyright (c) 2016-2017, HiQDev (http://hiqdev.com/) |
||
9 | */ |
||
10 | |||
11 | namespace hiqdev\assetpackagist\models; |
||
12 | |||
13 | use Composer\Package\Link; |
||
14 | use Exception; |
||
15 | use hiqdev\assetpackagist\components\Storage; |
||
16 | use hiqdev\assetpackagist\registry\RegistryFactory; |
||
17 | use hiqdev\assetpackagist\repositories\PackageRepository; |
||
18 | use Yii; |
||
19 | use yii\base\Object; |
||
20 | |||
21 | class AssetPackage extends Object |
||
0 ignored issues
–
show
|
|||
22 | { |
||
23 | protected $_type; |
||
24 | protected $_name; |
||
25 | protected $_hash; |
||
26 | /** |
||
27 | * @var array |
||
28 | */ |
||
29 | protected $_releases = []; |
||
30 | protected $_saved; |
||
31 | |||
32 | /** |
||
33 | * @var integer UNIX Epoch timestamp of the latest package update |
||
34 | */ |
||
35 | protected $_updateTime; |
||
36 | |||
37 | public static function normalizeName($name) |
||
38 | { |
||
39 | return strtolower(static::normalizeScopedName($name)); |
||
40 | } |
||
41 | |||
42 | public static function normalizeScopedName($name) |
||
43 | { |
||
44 | return preg_replace("#@(.+?)/#", '${1}--', $name); |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * AssetPackage constructor. |
||
49 | * @param string $type |
||
50 | * @param string $name |
||
51 | * @param array $config |
||
52 | * @throws Exception |
||
53 | */ |
||
54 | 1 | public function __construct($type, $name, $config = []) |
|
55 | { |
||
56 | 1 | parent::__construct($config); |
|
57 | |||
58 | 1 | if (!$this->checkType($type)) { |
|
59 | throw new Exception('wrong type'); |
||
60 | } |
||
61 | 1 | if (!$this->checkName($name)) { |
|
62 | throw new Exception('wrong name'); |
||
63 | } |
||
64 | 1 | $this->_type = $type; |
|
65 | 1 | $this->_name = $name; |
|
66 | 1 | } |
|
67 | |||
68 | /** |
||
69 | * @return RegistryFactory |
||
70 | */ |
||
71 | public function getRegistry() |
||
72 | { |
||
73 | return Yii::$app->get('registryFactory'); |
||
74 | } |
||
75 | |||
76 | 1 | public function checkType($type) |
|
77 | { |
||
78 | 1 | return $type === 'bower' || $type === 'npm'; |
|
79 | } |
||
80 | |||
81 | 1 | public function checkName($name) |
|
82 | { |
||
83 | 1 | return strlen($name) > 0; |
|
84 | } |
||
85 | |||
86 | 1 | public function getFullName() |
|
87 | { |
||
88 | 1 | return static::buildFullName($this->_type, $this->_name); |
|
89 | } |
||
90 | |||
91 | public static function buildNormalName($type, $name) |
||
92 | { |
||
93 | return static::buildFullName($type, static::normalizeName($name)); |
||
94 | } |
||
95 | |||
96 | 1 | public static function buildFullName($type, $name) |
|
97 | { |
||
98 | 1 | return $type . '-asset/' . $name; |
|
99 | } |
||
100 | |||
101 | public static function splitFullName($full) |
||
102 | { |
||
103 | list($temp, $name) = explode('/', $full); |
||
104 | list($type) = explode('-', $temp); |
||
105 | |||
106 | return [$type, $name]; |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * @param string $full package name |
||
111 | * @return static |
||
112 | */ |
||
113 | public static function fromFullName($full) |
||
114 | { |
||
115 | list($type, $name) = static::splitFullName($full); |
||
116 | return new static($type, $name); |
||
117 | } |
||
118 | |||
119 | public function getType() |
||
120 | { |
||
121 | return $this->_type; |
||
122 | } |
||
123 | |||
124 | public function getNormalName() |
||
125 | { |
||
126 | return static::buildNormalName($this->_type, $this->_name); |
||
127 | } |
||
128 | |||
129 | public function getName() |
||
130 | { |
||
131 | return $this->_name; |
||
132 | } |
||
133 | |||
134 | public function getHash() |
||
135 | { |
||
136 | return $this->_hash; |
||
137 | } |
||
138 | |||
139 | /** |
||
140 | * findOne. |
||
141 | * |
||
142 | * @param string $type |
||
143 | * @param string $name |
||
144 | * @return static|null |
||
145 | */ |
||
146 | public static function findOne($type, $name) |
||
147 | { |
||
148 | $package = new static($type, $name); |
||
149 | $package->load(); |
||
150 | |||
151 | return $package; |
||
152 | } |
||
153 | |||
154 | public function load() |
||
155 | { |
||
156 | $data = $this->getStorage()->readPackage($this); |
||
157 | if ($data !== null) { |
||
158 | $this->_hash = $data['hash']; |
||
159 | $this->_releases = $data['releases']; |
||
160 | $this->_updateTime = $data['updateTime']; |
||
161 | } |
||
162 | } |
||
163 | |||
164 | public function update() |
||
165 | { |
||
166 | $pool = $this->getRegistry()->getPool(); |
||
167 | $this->_releases = $this->prepareReleases($pool); |
||
168 | $this->getStorage()->writePackage($this); |
||
169 | $this->load(); |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * @param \Composer\DependencyResolver\Pool $pool |
||
174 | * @return array |
||
175 | */ |
||
176 | public function prepareReleases($pool) |
||
177 | { |
||
178 | $releases = []; |
||
179 | |||
180 | foreach ($pool->whatProvides($this->getFullName()) as $package) { |
||
181 | if ($package instanceof \Composer\Package\AliasPackage) { |
||
182 | continue; |
||
183 | } |
||
184 | |||
185 | $version = $this->prepareVersion($package->getPrettyVersion()); |
||
186 | $require = $this->prepareRequire($package->getRequires()); |
||
187 | $release = [ |
||
188 | 'uid' => $this->prepareUid($version), |
||
189 | 'name' => $this->getNormalName(), |
||
190 | 'version' => $version, |
||
191 | 'version_normalized' => $this->prepareVersion($package->getVersion()), |
||
192 | 'type' => $this->getType() . '-asset', |
||
193 | ]; |
||
194 | if ($require) { |
||
0 ignored issues
–
show
The expression
$require of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
195 | $release['require'] = $require; |
||
196 | } |
||
197 | if ($package->getDistUrl()) { |
||
198 | $release['dist'] = [ |
||
199 | 'type' => $package->getDistType(), |
||
200 | 'url' => $package->getDistUrl(), |
||
201 | 'reference' => $package->getDistReference(), |
||
202 | ]; |
||
203 | } |
||
204 | if ($package->getLicense()) { |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Composer\Package\PackageInterface as the method getLicense() does only exist in the following implementations of said interface: Composer\Package\AliasPackage , Composer\Package\CompletePackage , Composer\Package\RootAliasPackage , Composer\Package\RootPackage , Fxp\Composer\AssetPlugin...ractLazyCompletePackage , Fxp\Composer\AssetPlugin...age\LazyCompletePackage .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
205 | $release['license'] = $package->getLicense(); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Composer\Package\PackageInterface as the method getLicense() does only exist in the following implementations of said interface: Composer\Package\AliasPackage , Composer\Package\CompletePackage , Composer\Package\RootAliasPackage , Composer\Package\RootPackage , Fxp\Composer\AssetPlugin...ractLazyCompletePackage , Fxp\Composer\AssetPlugin...age\LazyCompletePackage .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
206 | } |
||
207 | if ($package->getSourceUrl()) { |
||
208 | $release['source'] = [ |
||
209 | 'type' => $package->getSourceType(), |
||
210 | 'url' => $package->getSourceUrl(), |
||
211 | 'reference' => $package->getSourceReference(), |
||
212 | ]; |
||
213 | } |
||
214 | if ((isset($release['dist']) && $release['dist']) || (isset($release['source']) && $release['source'])) { |
||
215 | $releases[$version] = $release; |
||
216 | } |
||
217 | } |
||
218 | |||
219 | //Sort before save |
||
220 | \hiqdev\assetpackagist\components\PackageUtil::sort($releases); |
||
221 | |||
222 | return $releases; |
||
223 | } |
||
224 | |||
225 | protected function prepareVersion($version) |
||
226 | { |
||
227 | if ($this->getNormalName() === 'bower-asset/angular') { |
||
228 | return $this->convertPatchToRC($version); |
||
229 | } |
||
230 | |||
231 | return $version; |
||
232 | } |
||
233 | |||
234 | protected function convertPatchToRC($version) |
||
235 | { |
||
236 | return preg_replace('/-patch(.+)/', '-RC${1}', $version); |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Prepares array of requires: name => constraint. |
||
241 | * @param Link[] array of package requires |
||
242 | * @return array |
||
243 | */ |
||
244 | public function prepareRequire(array $links) |
||
245 | { |
||
246 | $requires = []; |
||
247 | foreach ($links as $name => $link) { |
||
248 | /** @var Link $link */ |
||
249 | $requires[$name] = $link->getPrettyConstraint(); |
||
250 | } |
||
251 | |||
252 | return $requires; |
||
253 | } |
||
254 | |||
255 | public function prepareUid($version) |
||
256 | { |
||
257 | $known = $this->getSaved()->getRelease($version); |
||
258 | |||
259 | return isset($known['uid']) ? $known['uid'] : $this->getStorage()->getNextId(); |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * @return array |
||
264 | */ |
||
265 | public function getReleases() |
||
266 | { |
||
267 | return $this->_releases; |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * @param $version |
||
272 | * @return array |
||
273 | */ |
||
274 | public function getRelease($version) |
||
275 | { |
||
276 | return isset($this->_releases[$version]) ? $this->_releases[$version] : []; |
||
277 | } |
||
278 | |||
279 | public function getSaved() |
||
280 | { |
||
281 | if ($this->_saved === null) { |
||
282 | $this->_saved = static::findOne($this->getType(), $this->getName()); |
||
283 | } |
||
284 | |||
285 | return $this->_saved; |
||
286 | } |
||
287 | |||
288 | /** |
||
289 | * @return Storage |
||
290 | */ |
||
291 | public function getStorage() |
||
292 | { |
||
293 | return Yii::$app->get('packageStorage'); |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * Returns the latest update time (UNIX Epoch). |
||
298 | * @return int|null |
||
299 | */ |
||
300 | public function getUpdateTime() |
||
301 | { |
||
302 | return $this->_updateTime; |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * Package can be updated not more often than once in 10 min. |
||
307 | * @return bool |
||
308 | */ |
||
309 | public function canBeUpdated() |
||
310 | { |
||
311 | return time() - $this->getUpdateTime() > 60 * 10; // 10 min |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * Whether tha package should be auth-updated (if it is older than 1 day). |
||
316 | * @return bool |
||
317 | */ |
||
318 | public function canAutoUpdate() |
||
319 | { |
||
320 | return time() - $this->getUpdateTime() > 60 * 60 * 24; // 1 day |
||
321 | } |
||
322 | |||
323 | public function isAvailable() |
||
324 | { |
||
325 | $repository = Yii::createObject(PackageRepository::class, []); |
||
326 | |||
327 | return $repository->exists($this); |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @return array |
||
332 | */ |
||
333 | public function __sleep() |
||
334 | { |
||
335 | return ['_type', '_name', '_hash']; |
||
336 | } |
||
337 | } |
||
338 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.