Issues (31)

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/DataValues/UnboundedQuantityValue.php (4 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 DataValues;
4
5
use InvalidArgumentException;
6
7
/**
8
 * Class representing a quantity with associated unit.
9
 * The amount is stored as a @see DecimalValue object.
10
 *
11
 * @see QuantityValue for quantities with a known uncertainty interval.
12
 * For simple numeric amounts use @see NumberValue.
13
 *
14
 * @note UnboundedQuantityValue and QuantityValue both use the value type ID "quantity".
15
 * The fact that we use subclassing to model the bounded vs the unbounded case should be
16
 * considered an implementation detail.
17
 *
18
 * @since 0.8
19
 *
20
 * @license GPL-2.0-or-later
21
 * @author Daniel Kinzler
22
 */
23
class UnboundedQuantityValue extends DataValueObject {
24
25
	/**
26
	 * The quantity's amount
27
	 *
28
	 * @var DecimalValue
29
	 */
30
	protected $amount;
31
32
	/**
33
	 * The quantity's unit identifier (use "1" for unitless quantities).
34
	 *
35
	 * @var string
36
	 */
37
	protected $unit;
38
39
	/**
40
	 * @param DecimalValue $amount
41
	 * @param string $unit A unit identifier. Must not be empty, use "1" for unit-less quantities.
42
	 *
43
	 * @throws IllegalValueException
44
	 */
45 32
	public function __construct( DecimalValue $amount, $unit ) {
46 32
		if ( !is_string( $unit ) || $unit === '' ) {
47 2
			throw new IllegalValueException( '$unit must be a non-empty string. Use "1" for unit-less quantities.' );
48
		}
49
50 30
		$this->amount = $amount;
51 30
		$this->unit = $unit;
52 30
	}
53
54
	/**
55
	 * Returns a QuantityValue representing the given amount.
56
	 *
57
	 * This is a convenience wrapper around the constructor that accepts native values
58
	 * instead of DecimalValue objects.
59
	 *
60
	 * @note if the amount or a bound is given as a string, the string must conform
61
	 * to the rules defined by @see DecimalValue.
62
	 *
63
	 * @param string|int|float|DecimalValue $amount
64
	 * @param string $unit A unit identifier. Must not be empty, use "1" for unit-less quantities.
65
	 *
66
	 * @return self
67
	 * @throws InvalidArgumentException
68
	 */
69 7
	public static function newFromNumber( $amount, $unit = '1' ) {
70 7
		$amount = self::asDecimalValue( 'amount', $amount );
71
72 7
		return new self( $amount, $unit );
73
	}
74
75
	/**
76
	 * Converts $number to a DecimalValue if possible and necessary.
77
	 *
78
	 * @note if the $number is given as a string, it must conform to the rules
79
	 *        defined by @see DecimalValue.
80
	 *
81
	 * @param string $name The variable name to use in exception messages
82
	 * @param string|int|float|DecimalValue|null $number
83
	 * @param DecimalValue|null $default
84
	 *
85
	 * @throws InvalidArgumentException
86
	 * @return DecimalValue
87
	 */
88 7
	protected static function asDecimalValue( $name, $number, DecimalValue $default = null ) {
89 7
		if ( !is_string( $name ) ) {
90
			throw new InvalidArgumentException( '$name must be a string' );
91
		}
92
93 7
		if ( $number === null ) {
94
			if ( $default === null ) {
95
				throw new InvalidArgumentException( '$' . $name . ' must not be null' );
96
			}
97
98
			$number = $default;
99
		}
100
101 7
		if ( $number instanceof DecimalValue ) {
102
			// nothing to do
103 6
		} elseif ( is_int( $number ) || is_float( $number ) || is_string( $number ) ) {
104 6
			$number = new DecimalValue( $number );
105
		} else {
106
			throw new IllegalValueException( '$' . $name . '  must be a string, int, or float' );
107
		}
108
109 7
		return $number;
110
	}
111
112
	/**
113
	 * @see Serializable::serialize
114
	 *
115
	 * @return string
116
	 */
117 9
	public function serialize() {
118 9
		return serialize( [
119 9
			$this->amount,
120 9
			$this->unit
121
		] );
122
	}
123
124
	/**
125
	 * @see Serializable::unserialize
126
	 *
127
	 * @param string $data
128
	 */
129 9
	public function unserialize( $data ) {
130 9
		list( $amount, $unit ) = unserialize( $data );
131 9
		$this->__construct( $amount, $unit );
132 9
	}
133
134
	/**
135
	 * @see DataValue::getType
136
	 *
137
	 * @return string
138
	 */
139 15
	public static function getType() {
140 15
		return 'quantity';
141
	}
142
143
	/**
144
	 * @deprecated Kept for compatibility with older DataValues versions.
145
	 * Do not use.
146
	 *
147
	 * @return float
148 3
	 */
149 3
	public function getSortKey() {
150
		return $this->amount->getValueFloat();
151
	}
152
153
	/**
154
	 * Returns the quantity object.
155
	 * @see DataValue::getValue
156
	 *
157
	 * @return self
158 6
	 */
159 6
	public function getValue() {
160
		return $this;
161
	}
162
163
	/**
164
	 * Returns the amount represented by this quantity.
165
	 *
166
	 * @return DecimalValue
167 20
	 */
168 20
	public function getAmount() {
169
		return $this->amount;
170
	}
171
172
	/**
173
	 * Returns the unit held by this quantity.
174
	 * Unit-less quantities should use "1" as their unit.
175
	 *
176
	 * @return string
177 10
	 */
178 10
	public function getUnit() {
179
		return $this->unit;
180
	}
181
182
	/**
183
	 * Returns a transformed value derived from this QuantityValue by applying
184
	 * the given transformation to the amount and the upper and lower bounds.
185
	 * The resulting amount and bounds are rounded to the significant number of
186
	 * digits. Note that for exact quantities (with at least one bound equal to
187
	 * the amount), no rounding is applied (since they are considered to have
188
	 * infinite precision).
189
	 *
190
	 * The transformation is provided as a callback, which must implement a
191
	 * monotonously increasing, fully differentiable function mapping a DecimalValue
192
	 * to a DecimalValue. Typically, it will be a linear transformation applying a
193
	 * factor and an offset.
194
	 *
195
	 * @param string $newUnit The unit of the transformed quantity.
196
	 *
197
	 * @param callable $transformation A callback that implements the desired transformation.
198
	 *        The transformation will be called three times, once for the amount, once
199
	 *        for the lower bound, and once for the upper bound. It must return a DecimalValue.
200
	 *        The first parameter passed to $transformation is the DecimalValue to transform
201
	 *        In addition, any extra parameters passed to transform() will be passed through
202
	 *        to the transformation callback.
203
	 *
204
	 * @param mixed ... Any extra parameters will be passed to the $transformation function.
205
	 *
206
	 * @todo Should be factored out into a separate QuantityMath class.
207
	 *
208
	 * @throws InvalidArgumentException
209
	 * @return self
210 7
	 */
211 7
	public function transform( $newUnit, $transformation ) {
212
		if ( !is_callable( $transformation ) ) {
213
			throw new InvalidArgumentException( '$transformation must be callable.' );
214
		}
215 7
216
		if ( !is_string( $newUnit ) || $newUnit === '' ) {
217
			throw new InvalidArgumentException(
218
				'$newUnit must be a non-empty string. Use "1" for unit-less quantities.'
219
			);
220
		}
221
222
		// Apply transformation by calling the $transform callback.
223
		// The first argument for the callback is the DataValue to transform. In addition,
224 7
		// any extra arguments given for transform() are passed through.
225 7
		$args = func_get_args();
226
		array_shift( $args );
227 7
228 7
		$args[0] = $this->amount;
229
		$amount = call_user_func_array( $transformation, $args );
230 7
231
		return new self( $amount, $newUnit );
232
	}
233 2
234 2
	public function __toString() {
235 2
		return $this->amount->getValue()
236
			. ( $this->unit === '1' ? '' : $this->unit );
237
	}
238
239
	/**
240
	 * @see DataValue::getArrayValue
241
	 *
242
	 * @return array
243 15
	 */
244
	public function getArrayValue() {
245 15
		return [
246 15
			'amount' => $this->amount->getArrayValue(),
247
			'unit' => $this->unit,
248
		];
249
	}
250
251
	/**
252
	 * Static helper capable of constructing both unbounded and bounded quantity value objects,
253
	 * depending on the serialization provided. Required for @see DataValueDeserializer.
254
	 * This is expected to round-trip with both @see getArrayValue as well as
255
	 * @see QuantityValue::getArrayValue.
256
	 *
257
	 * @deprecated since 0.8.3. Static DataValue::newFromArray constructors like this are
258
	 *  underspecified (not in the DataValue interface), and misleadingly named (should be named
259
	 *  newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
260
	 *
261
	 * @param mixed $data Warning! Even if this is expected to be a value as returned by
262
	 *  @see getArrayValue, callers of this specific newFromArray implementation can not guarantee
263
	 *  this. This is not even guaranteed to be an array!
264
	 *
265
	 * @throws IllegalValueException if $data is not in the expected format. Subclasses of
266
	 *  InvalidArgumentException are expected and properly handled by @see DataValueDeserializer.
267
	 * @return self|QuantityValue Either an unbounded or bounded quantity value object.
268
	 */
269
	public static function newFromArray( $data ) {
270
		self::requireArrayFields( $data, [ 'amount', 'unit' ] );
271
272
		if ( !isset( $data['upperBound'] ) && !isset( $data['lowerBound'] ) ) {
273
			return new self(
274
				DecimalValue::newFromArray( $data['amount'] ),
0 ignored issues
show
Deprecated Code introduced by
The method DataValues\DecimalValue::newFromArray() has been deprecated with message: since 0.8.3. Static DataValue::newFromArray constructors like this are underspecified (not in the DataValue interface), and misleadingly named (should be named newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
275
				$data['unit']
276
			);
277
		} else {
278
			self::requireArrayFields( $data, [ 'upperBound', 'lowerBound' ] );
279
280
			return new QuantityValue(
281
				DecimalValue::newFromArray( $data['amount'] ),
0 ignored issues
show
Deprecated Code introduced by
The method DataValues\DecimalValue::newFromArray() has been deprecated with message: since 0.8.3. Static DataValue::newFromArray constructors like this are underspecified (not in the DataValue interface), and misleadingly named (should be named newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
282
				$data['unit'],
283
				DecimalValue::newFromArray( $data['upperBound'] ),
0 ignored issues
show
Deprecated Code introduced by
The method DataValues\DecimalValue::newFromArray() has been deprecated with message: since 0.8.3. Static DataValue::newFromArray constructors like this are underspecified (not in the DataValue interface), and misleadingly named (should be named newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
284
				DecimalValue::newFromArray( $data['lowerBound'] )
0 ignored issues
show
Deprecated Code introduced by
The method DataValues\DecimalValue::newFromArray() has been deprecated with message: since 0.8.3. Static DataValue::newFromArray constructors like this are underspecified (not in the DataValue interface), and misleadingly named (should be named newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
285
			);
286
		}
287
	}
288
289
	/**
290
	 *
291
	 * @param mixed $target
292
	 *
293
	 * @return bool
294
	 */
295 12
	public function equals( $target ) {
296 12
		if ( $this === $target ) {
297 3
			return true;
298
		}
299
300 12
		return $target instanceof self
301 12
			&& $this->toArray() === $target->toArray();
302
	}
303
304
}
305