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 | namespace PhpAmqpLib\Wire; |
||
3 | |||
4 | use PhpAmqpLib\Channel\AMQPChannel; |
||
5 | |||
6 | /** |
||
7 | * Abstract base class for AMQP content. Subclasses should override |
||
8 | * the propertyDefinitions attribute. |
||
9 | */ |
||
10 | abstract class GenericContent |
||
11 | { |
||
12 | /** @var AMQPChannel[] */ |
||
13 | public $delivery_info = array(); |
||
14 | |||
15 | /** @var array Final property definitions */ |
||
16 | protected $prop_types; |
||
17 | |||
18 | /** @var array Properties content */ |
||
19 | private $properties = array(); |
||
20 | |||
21 | /** @var string Compiled properties */ |
||
22 | private $serialized_properties; |
||
23 | |||
24 | /** |
||
25 | * @var array |
||
26 | */ |
||
27 | protected static $propertyDefinitions = array( |
||
28 | 'dummy' => 'shortstr' |
||
29 | ); |
||
30 | |||
31 | /** |
||
32 | * @param array $props Message property content |
||
33 | * @param array $prop_types Message property definitions |
||
34 | */ |
||
35 | 130 | public function __construct($props = array(), $prop_types = array()) |
|
36 | { |
||
37 | 130 | $this->prop_types = self::$propertyDefinitions; |
|
38 | |||
39 | 130 | if (!empty($prop_types)) { |
|
40 | 130 | $this->prop_types = $prop_types; |
|
41 | 104 | } |
|
42 | |||
43 | 130 | if (!empty($props)) { |
|
44 | 120 | $this->properties = array_intersect_key($props, $this->prop_types); |
|
45 | 96 | } |
|
46 | 130 | } |
|
47 | |||
48 | /** |
||
49 | * Check whether a property exists in the 'properties' dictionary |
||
50 | * or if present - in the 'delivery_info' dictionary. |
||
51 | * |
||
52 | * @param string $name |
||
53 | * @return bool |
||
54 | */ |
||
55 | public function has($name) |
||
56 | { |
||
57 | return isset($this->properties[$name]) || isset($this->delivery_info[$name]); |
||
58 | } |
||
59 | |||
60 | /** |
||
61 | * Look for additional properties in the 'properties' dictionary, |
||
62 | * and if present - the 'delivery_info' dictionary. |
||
63 | * |
||
64 | * @param string $name |
||
65 | * @throws \OutOfBoundsException |
||
66 | * @return mixed|AMQPChannel |
||
67 | */ |
||
68 | 15 | public function get($name) |
|
69 | { |
||
70 | 15 | if (isset($this->properties[$name])) { |
|
71 | 15 | return $this->properties[$name]; |
|
72 | } |
||
73 | |||
74 | 10 | if (isset($this->delivery_info[$name])) { |
|
75 | return $this->delivery_info[$name]; |
||
76 | } |
||
77 | |||
78 | 10 | throw new \OutOfBoundsException(sprintf( |
|
79 | 10 | 'No "%s" property', |
|
80 | $name |
||
81 | 8 | )); |
|
82 | } |
||
83 | |||
84 | /** |
||
85 | * Returns the properties content |
||
86 | * |
||
87 | * @return array |
||
88 | */ |
||
89 | 75 | public function get_properties() |
|
90 | { |
||
91 | 75 | return $this->properties; |
|
92 | } |
||
93 | |||
94 | /** |
||
95 | * Sets a property value |
||
96 | * |
||
97 | * @param string $name The property name (one of the property definition) |
||
98 | * @param mixed $value The property value |
||
99 | * @throws \OutOfBoundsException |
||
100 | */ |
||
101 | 5 | public function set($name, $value) |
|
102 | { |
||
103 | 5 | if (!array_key_exists($name, $this->prop_types)) { |
|
104 | throw new \OutOfBoundsException(sprintf( |
||
105 | 'No "%s" property', |
||
106 | $name |
||
107 | )); |
||
108 | } |
||
109 | |||
110 | 5 | $this->properties[$name] = $value; |
|
111 | 5 | } |
|
112 | |||
113 | /** |
||
114 | * Given the raw bytes containing the property-flags and |
||
115 | * property-list from a content-frame-header, parse and insert |
||
116 | * into a dictionary stored in this object as an attribute named |
||
117 | * 'properties'. |
||
118 | * |
||
119 | * @param AMQPReader $reader |
||
120 | * NOTE: do not mutate $reader |
||
121 | * @return $this |
||
122 | */ |
||
123 | 120 | public function load_properties($reader) |
|
124 | { |
||
125 | // Read 16-bit shorts until we get one with a low bit set to zero |
||
126 | 120 | $flags = array(); |
|
127 | |||
128 | 120 | while (true) { |
|
129 | 120 | $flag_bits = $reader->read_short(); |
|
130 | 120 | $flags[] = $flag_bits; |
|
131 | |||
132 | 120 | if (($flag_bits & 1) === 0) { |
|
133 | 120 | break; |
|
134 | } |
||
135 | } |
||
136 | |||
137 | 120 | $shift = 0; |
|
138 | 120 | $data = array(); |
|
139 | |||
140 | 120 | foreach ($this->prop_types as $key => $proptype) { |
|
141 | 120 | if ($shift === 0) { |
|
142 | 120 | if (!$flags) { |
|
0 ignored issues
–
show
|
|||
143 | break; |
||
144 | } |
||
145 | 120 | $flag_bits = array_shift($flags); |
|
146 | 120 | $shift = 15; |
|
147 | 96 | } |
|
148 | |||
149 | 120 | if ($flag_bits & (1 << $shift)) { |
|
0 ignored issues
–
show
The variable
$flag_bits does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
150 | 105 | $data[$key] = $reader->{'read_' . $proptype}(); |
|
151 | 84 | } |
|
152 | |||
153 | 120 | $shift -= 1; |
|
154 | 96 | } |
|
155 | |||
156 | 120 | $this->properties = $data; |
|
157 | |||
158 | 120 | return $this; |
|
159 | } |
||
160 | |||
161 | |||
162 | /** |
||
163 | * Serializes the 'properties' attribute (a dictionary) into the |
||
164 | * raw bytes making up a set of property flags and a property |
||
165 | * list, suitable for putting into a content frame header. |
||
166 | * |
||
167 | * @return string |
||
168 | * @todo Inject the AMQPWriter to make the method easier to test |
||
169 | */ |
||
170 | 130 | public function serialize_properties() |
|
171 | { |
||
172 | 130 | if (!empty($this->serialized_properties)) { |
|
173 | 10 | return $this->serialized_properties; |
|
174 | } |
||
175 | |||
176 | 130 | $shift = 15; |
|
177 | 130 | $flag_bits = 0; |
|
178 | 130 | $flags = array(); |
|
179 | 130 | $raw_bytes = new AMQPWriter(); |
|
180 | |||
181 | 130 | foreach ($this->prop_types as $key => $prototype) { |
|
182 | 130 | $val = isset($this->properties[$key]) ? $this->properties[$key] : null; |
|
183 | |||
184 | // Very important: PHP type eval is weak, use the === to test the |
||
185 | // value content. Zero or false value should not be removed |
||
186 | 130 | if ($val === null) { |
|
187 | 130 | $shift -= 1; |
|
188 | 130 | continue; |
|
189 | } |
||
190 | |||
191 | 115 | if ($shift === 0) { |
|
192 | $flags[] = $flag_bits; |
||
193 | $flag_bits = 0; |
||
194 | $shift = 15; |
||
195 | } |
||
196 | |||
197 | 115 | $flag_bits |= (1 << $shift); |
|
198 | 115 | if ($prototype != 'bit') { |
|
199 | 115 | $raw_bytes->{'write_' . $prototype}($val); |
|
200 | 92 | } |
|
201 | |||
202 | 115 | $shift -= 1; |
|
203 | 104 | } |
|
204 | |||
205 | 130 | $flags[] = $flag_bits; |
|
206 | 130 | $result = new AMQPWriter(); |
|
207 | 130 | foreach ($flags as $flag_bits) { |
|
208 | 130 | $result->write_short($flag_bits); |
|
209 | 104 | } |
|
210 | |||
211 | 130 | $result->write($raw_bytes->getvalue()); |
|
212 | |||
213 | 130 | $this->serialized_properties = $result->getvalue(); |
|
214 | |||
215 | 130 | return $this->serialized_properties; |
|
216 | } |
||
217 | } |
||
218 |
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
empty(..)
or! empty(...)
instead.