Issues (55)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/ReferenceList.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Wikibase\DataModel;
4
5
use ArrayIterator;
6
use Countable;
7
use InvalidArgumentException;
8
use IteratorAggregate;
9
use Serializable;
10
use Traversable;
11
use Wikibase\DataModel\Internal\MapValueHasher;
12
use Wikibase\DataModel\Snak\Snak;
13
14
/**
15
 * List of Reference objects.
16
 *
17
 * @since 0.1
18
 * Does not implement References anymore since 2.0
19
 * Does not extend SplObjectStorage since 5.0
20
 *
21
 * @license GPL-2.0-or-later
22
 * @author Jeroen De Dauw < [email protected] >
23
 * @author H. Snater < [email protected] >
24
 * @author Thiemo Kreuz
25
 * @author Bene* < [email protected] >
26
 */
27
class ReferenceList implements Countable, IteratorAggregate, Serializable {
28
29
	/**
30
	 * @var Reference[] Ordered list or references, indexed by SPL object hash.
31
	 */
32
	private $references = [];
33
34 29
	/**
35 29
	 * @param Reference[]|Traversable $references
36 8
	 *
37
	 * @throws InvalidArgumentException
38
	 */
39 21
	public function __construct( $references = [] ) {
40 12
		if ( !is_array( $references ) && !( $references instanceof Traversable ) ) {
41 4
			throw new InvalidArgumentException( '$references must be an array or an instance of Traversable' );
42
		}
43
44 8
		foreach ( $references as $reference ) {
45 17
			if ( !( $reference instanceof Reference ) ) {
46 17
				throw new InvalidArgumentException( 'Every element in $references must be an instance of Reference' );
47
			}
48
49
			$this->addReference( $reference );
50
		}
51
	}
52
53
	/**
54
	 * Adds the provided reference to the list.
55
	 * Empty references are ignored.
56
	 *
57
	 * @since 0.1
58 14
	 *
59 14
	 * @param Reference $reference
60
	 * @param int|null $index New position of the added reference, or null to append.
61
	 *
62
	 * @throws InvalidArgumentException
63 14
	 */
64
	public function addReference( Reference $reference, $index = null ) {
65 14
		if ( $index !== null && ( !is_int( $index ) || $index < 0 ) ) {
66 14
			throw new InvalidArgumentException( '$index must be a non-negative integer or null' );
67 2
		}
68
69 14
		if ( $reference->isEmpty() ) {
70
			return;
71
		}
72
73
		$splHash = spl_object_hash( $reference );
74
75
		if ( array_key_exists( $splHash, $this->references ) ) {
76
			return;
77 14
		}
78 14
79 14
		if ( $index === null || $index >= count( $this->references ) ) {
80 14
			// Append object to the end of the reference list.
81 14
			$this->references[$splHash] = $reference;
82
		} else {
83
			$this->insertReferenceAtIndex( $reference, $index );
84
		}
85
	}
86
87
	/**
88
	 * @since 1.1
89
	 *
90
	 * @param Snak ...$snaks
91 6
	 * (passing a single Snak[] is still supported but deprecated)
92 6
	 *
93 5
	 * @throws InvalidArgumentException
94 5
	 */
95
	public function addNewReference( ...$snaks ) {
96 6
		if ( count( $snaks ) === 1 && is_array( $snaks[0] ) ) {
97 5
			// TODO stop supporting this
98
			$snaks = $snaks[0];
99
		}
100
101
		$this->addReference( new Reference( $snaks ) );
102
	}
103 2
104 2
	/**
105 2
	 * @param Reference $reference
106
	 * @param int $index
107
	 */
108 2
	private function insertReferenceAtIndex( Reference $reference, $index ) {
109 2
		if ( !is_int( $index ) ) {
110 2
			throw new InvalidArgumentException( '$index must be an integer' );
111 2
		}
112 2
113
		$splHash = spl_object_hash( $reference );
114 2
115 2
		$this->references = array_merge(
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge(array_slice(...s->references, $index)) of type array<integer|string,obj...e\DataModel\Reference>> is incompatible with the declared type array<integer,object<Wik...e\DataModel\Reference>> of property $references.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
116 2
			array_slice( $this->references, 0, $index ),
117
			[ $splHash => $reference ],
118
			array_slice( $this->references, $index )
119 2
		);
120
	}
121 2
122 2
	/**
123 2
	 * Returns if the list contains a reference with the same hash as the provided reference.
124 2
	 *
125
	 * @since 0.1
126
	 *
127
	 * @param Reference $reference
128
	 *
129
	 * @return bool
130
	 */
131
	public function hasReference( Reference $reference ) {
132
		return $this->hasReferenceHash( $reference->getHash() );
133
	}
134
135 6
	/**
136 6
	 * Returns the index of the Reference object or false if the Reference could not be found.
137 6
	 *
138
	 * @since 0.5
139
	 *
140
	 * @param Reference $reference
141
	 *
142
	 * @return int|bool
143
	 */
144
	public function indexOf( Reference $reference ) {
145
		$index = 0;
146
147
		foreach ( $this->references as $ref ) {
148
			if ( $ref === $reference ) {
149 2
				return $index;
150 2
			}
151
152 2
			$index++;
153 1
		}
154 1
155
		return false;
156 1
	}
157 2
158
	/**
159 2
	 * Removes the reference with the same hash as the provided reference if such a reference exists in the list.
160
	 *
161
	 * @since 0.1
162
	 *
163
	 * @param Reference $reference
164
	 */
165
	public function removeReference( Reference $reference ) {
166
		$this->removeReferenceHash( $reference->getHash() );
167
	}
168
169 3
	/**
170 3
	 * Returns if the list contains a reference with the provided hash.
171 3
	 *
172
	 * @since 0.3
173
	 *
174
	 * @param string $referenceHash
175
	 *
176
	 * @return bool
177
	 */
178
	public function hasReferenceHash( $referenceHash ) {
179
		return $this->getReference( $referenceHash ) !== null;
180
	}
181
182 8
	/**
183 8
	 * Looks for the first Reference object in this list with the provided hash.
184
	 * Removes all occurences of that object.
185
	 *
186
	 * @since 0.3
187
	 *
188
	 * @param string $referenceHash	`
189
	 */
190
	public function removeReferenceHash( $referenceHash ) {
191
		$reference = $this->getReference( $referenceHash );
192
193 5
		if ( $reference === null ) {
194 5
			return;
195
		}
196 5
197 3
		foreach ( $this->references as $splObjectHash => $ref ) {
198 3
			if ( $ref === $reference ) {
199 5
				unset( $this->references[$splObjectHash] );
200
			}
201
		}
202
	}
203
204
	/**
205
	 * Returns the first Reference object with the provided hash, or
206
	 * null if there is no such reference in the list.
207
	 *
208
	 * @since 0.3
209
	 *
210 14
	 * @param string $referenceHash
211
	 *
212
	 * @return Reference|null
213
	 */
214 14
	public function getReference( $referenceHash ) {
215 10
		foreach ( $this->references as $reference ) {
216 10
			if ( $reference->getHash() === $referenceHash ) {
217
				return $reference;
218 9
			}
219
		}
220 9
221
		return null;
222
	}
223
224
	/**
225
	 * @see Serializable::serialize
226
	 *
227
	 * @since 2.1
228
	 *
229
	 * @return string
230 3
	 */
231 3
	public function serialize() {
232
		return serialize( array_values( $this->references ) );
233
	}
234
235
	/**
236
	 * @see https://wiki.php.net/rfc/custom_object_serialization
237
	 *
238
	 * @return array
239
	 */
240
	public function __serialize() {
241 3
		return [
242 3
			'references' => array_values( $this->references )
243 3
		];
244
	}
245
246
	/**
247
	 * @see https://wiki.php.net/rfc/custom_object_serialization
248
	 *
249
	 * @param array $data
250 3
	 */
251 3
	public function __unserialize( array $data ) : void {
252
		$this->references = $data['references'];
253
	}
254
255
	/**
256
	 * @see Serializable::unserialize
257
	 *
258
	 * @since 2.1
259
	 *
260
	 * @param string $serialized
261
	 */
262
	public function unserialize( $serialized ) {
263
		$this->__construct( unserialize( $serialized ) );
264
	}
265
266
	/**
267
	 * @since 4.4
268
	 *
269
	 * @return bool
270
	 */
271
	public function isEmpty() {
272
		return empty( $this->references );
273
	}
274
275
	/**
276
	 * The hash is purely valuer based. Order of the elements in the array is not held into account.
277
	 *
278
	 * @since 0.3
279
	 *
280
	 * @return string
281
	 */
282
	public function getValueHash() {
283
		$hasher = new MapValueHasher();
284
		return $hasher->hash( $this->references );
0 ignored issues
show
$this->references is of type array<integer,object<Wik...e\DataModel\Reference>>, but the function expects a object<Traversable>.

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...
285
	}
286
287
	/**
288
	 * The comparison is done purely value based, ignoring the order of the elements in the array.
289
	 *
290
	 * @since 0.3
291
	 *
292
	 * @param mixed $target
293
	 *
294
	 * @return bool
295
	 */
296
	public function equals( $target ) {
297
		if ( $this === $target ) {
298
			return true;
299
		}
300
301
		return $target instanceof self
302
			&& $this->getValueHash() === $target->getValueHash();
303
	}
304
305
	/**
306
	 * @see Countable::count
307
	 *
308
	 * @return int
309
	 */
310
	public function count() {
311
		return count( $this->references );
312
	}
313
314
	/**
315
	 * @see IteratorAggregate::getIterator
316
	 *
317
	 * @since 5.0
318
	 *
319
	 * @return Iterator|Reference[]
320
	 */
321
	public function getIterator() {
322
		return new ArrayIterator( array_values( $this->references ) );
323
	}
324
325
}
326