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 GuzzleHttp\Command\Guzzle\RequestLocation; |
||
3 | |||
4 | use GuzzleHttp\Command\CommandInterface; |
||
5 | use GuzzleHttp\Command\Guzzle\Operation; |
||
6 | use GuzzleHttp\Command\Guzzle\Parameter; |
||
7 | use GuzzleHttp\Psr7; |
||
8 | use Psr\Http\Message\RequestInterface; |
||
9 | |||
10 | /** |
||
11 | * Creates an XML document |
||
12 | */ |
||
13 | class XmlLocation extends AbstractLocation |
||
14 | { |
||
15 | /** @var \XMLWriter XML writer resource */ |
||
16 | private $writer; |
||
17 | |||
18 | /** @var string Content-Type header added when XML is found */ |
||
19 | private $contentType; |
||
20 | |||
21 | /** @var Parameter[] Buffered elements to write */ |
||
22 | private $buffered = []; |
||
23 | |||
24 | /** |
||
25 | * @param string $locationName Name of the location |
||
26 | * @param string $contentType Set to a non-empty string to add a |
||
27 | * Content-Type header to a request if any XML content is added to the |
||
28 | * body. Pass an empty string to disable the addition of the header. |
||
29 | */ |
||
30 | 4 | public function __construct($locationName = 'xml', $contentType = 'application/xml') |
|
31 | { |
||
32 | 4 | parent::__construct($locationName); |
|
33 | 4 | $this->contentType = $contentType; |
|
34 | 4 | } |
|
35 | |||
36 | /** |
||
37 | * @param CommandInterface $command |
||
38 | * @param RequestInterface $request |
||
39 | * @param Parameter $param |
||
40 | * |
||
41 | * @return RequestInterface |
||
42 | */ |
||
43 | 17 | public function visit( |
|
44 | CommandInterface $command, |
||
45 | RequestInterface $request, |
||
46 | Parameter $param |
||
47 | ) { |
||
48 | // Buffer and order the parameters to visit based on if they are |
||
49 | // top-level attributes or child nodes. |
||
50 | // @link https://github.com/guzzle/guzzle/pull/494 |
||
51 | 17 | if ($param->getData('xmlAttribute')) { |
|
52 | 2 | array_unshift($this->buffered, $param); |
|
53 | 2 | } else { |
|
54 | 16 | $this->buffered[] = $param; |
|
55 | } |
||
56 | |||
57 | 17 | return $request; |
|
58 | } |
||
59 | |||
60 | /** |
||
61 | * @param CommandInterface $command |
||
62 | * @param RequestInterface $request |
||
63 | * @param Operation $operation |
||
64 | * |
||
65 | * @return RequestInterface |
||
66 | */ |
||
67 | 18 | public function after( |
|
68 | CommandInterface $command, |
||
69 | RequestInterface $request, |
||
70 | Operation $operation |
||
71 | ) { |
||
72 | 18 | foreach ($this->buffered as $param) { |
|
73 | 17 | $this->visitWithValue( |
|
74 | 17 | $command[$param->getName()], |
|
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
75 | 17 | $param, |
|
76 | $operation |
||
77 | 17 | ); |
|
78 | 18 | } |
|
79 | |||
80 | 18 | $this->buffered = []; |
|
81 | |||
82 | 18 | $additional = $operation->getAdditionalParameters(); |
|
83 | 18 | View Code Duplication | if ($additional && $additional->getLocation() == $this->locationName) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
84 | 1 | foreach ($command->toArray() as $key => $value) { |
|
85 | 1 | if (!$operation->hasParam($key)) { |
|
86 | 1 | $additional->setName($key); |
|
87 | 1 | $this->visitWithValue($value, $additional, $operation); |
|
88 | 1 | } |
|
89 | 1 | } |
|
90 | 1 | $additional->setName(null); |
|
91 | 1 | } |
|
92 | |||
93 | // If data was found that needs to be serialized, then do so |
||
94 | 18 | $xml = ''; |
|
95 | 18 | if ($this->writer) { |
|
96 | 17 | $xml = $this->finishDocument($this->writer); |
|
97 | 18 | } elseif ($operation->getData('xmlAllowEmpty')) { |
|
98 | // Check if XML should always be sent for the command |
||
99 | 1 | $writer = $this->createRootElement($operation); |
|
100 | 1 | $xml = $this->finishDocument($writer); |
|
101 | 1 | } |
|
102 | |||
103 | 18 | if ($xml !== '') { |
|
104 | 18 | $request = $request->withBody(Psr7\stream_for($xml)); |
|
105 | // Don't overwrite the Content-Type if one is set |
||
106 | 18 | if ($this->contentType && !$request->hasHeader('Content-Type')) { |
|
107 | 18 | $request = $request->withHeader('Content-Type', $this->contentType); |
|
108 | 18 | } |
|
109 | 18 | } |
|
110 | |||
111 | 18 | $this->writer = null; |
|
112 | |||
113 | 18 | return $request; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * Create the root XML element to use with a request |
||
118 | * |
||
119 | * @param Operation $operation Operation object |
||
120 | * |
||
121 | * @return \XMLWriter |
||
122 | */ |
||
123 | 18 | protected function createRootElement(Operation $operation) |
|
124 | { |
||
125 | 18 | static $defaultRoot = ['name' => 'Request']; |
|
126 | // If no root element was specified, then just wrap the XML in 'Request' |
||
127 | 18 | $root = $operation->getData('xmlRoot') ?: $defaultRoot; |
|
128 | // Allow the XML declaration to be customized with xmlEncoding |
||
129 | 18 | $encoding = $operation->getData('xmlEncoding'); |
|
130 | 18 | $writer = $this->startDocument($encoding); |
|
131 | 18 | $writer->startElement($root['name']); |
|
132 | |||
133 | // Create the wrapping element with no namespaces if no namespaces were present |
||
134 | 18 | if (!empty($root['namespaces'])) { |
|
135 | // Create the wrapping element with an array of one or more namespaces |
||
136 | 1 | foreach ((array) $root['namespaces'] as $prefix => $uri) { |
|
137 | 1 | $nsLabel = 'xmlns'; |
|
138 | 1 | if (!is_numeric($prefix)) { |
|
139 | $nsLabel .= ':'.$prefix; |
||
140 | } |
||
141 | 1 | $writer->writeAttribute($nsLabel, $uri); |
|
142 | 1 | } |
|
143 | 1 | } |
|
144 | |||
145 | 18 | return $writer; |
|
146 | } |
||
147 | |||
148 | /** |
||
149 | * Recursively build the XML body |
||
150 | * |
||
151 | * @param \XMLWriter $writer XML to modify |
||
152 | * @param Parameter $param API Parameter |
||
153 | * @param mixed $value Value to add |
||
154 | */ |
||
155 | 17 | protected function addXml(\XMLWriter $writer, Parameter $param, $value) |
|
156 | { |
||
157 | 17 | $value = $param->filter($value); |
|
158 | 17 | $type = $param->getType(); |
|
159 | 17 | $name = $param->getWireName(); |
|
160 | 17 | $prefix = null; |
|
161 | 17 | $namespace = $param->getData('xmlNamespace'); |
|
162 | 17 | if (false !== strpos($name, ':')) { |
|
163 | 2 | list($prefix, $name) = explode(':', $name, 2); |
|
164 | 2 | } |
|
165 | |||
166 | 17 | if ($type == 'object' || $type == 'array') { |
|
167 | 9 | if (!$param->getData('xmlFlattened')) { |
|
168 | 9 | if ($namespace) { |
|
169 | $writer->startElementNS(null, $name, $namespace); |
||
170 | } else { |
||
171 | 9 | $writer->startElement($name); |
|
172 | } |
||
173 | 9 | } |
|
174 | 9 | if ($param->getType() == 'array') { |
|
175 | 4 | $this->addXmlArray($writer, $param, $value); |
|
176 | 9 | } elseif ($param->getType() == 'object') { |
|
177 | 8 | $this->addXmlObject($writer, $param, $value); |
|
178 | 8 | } |
|
179 | 9 | if (!$param->getData('xmlFlattened')) { |
|
180 | 9 | $writer->endElement(); |
|
181 | 9 | } |
|
182 | 9 | return; |
|
183 | } |
||
184 | 17 | if ($param->getData('xmlAttribute')) { |
|
185 | 5 | $this->writeAttribute($writer, $prefix, $name, $namespace, $value); |
|
186 | 5 | } else { |
|
187 | 15 | $this->writeElement($writer, $prefix, $name, $namespace, $value); |
|
188 | } |
||
189 | 17 | } |
|
190 | |||
191 | /** |
||
192 | * Write an attribute with namespace if used |
||
193 | * |
||
194 | * @param \XMLWriter $writer XMLWriter instance |
||
195 | * @param string $prefix Namespace prefix if any |
||
196 | * @param string $name Attribute name |
||
197 | * @param string $namespace The uri of the namespace |
||
198 | * @param string $value The attribute content |
||
199 | */ |
||
200 | 5 | protected function writeAttribute($writer, $prefix, $name, $namespace, $value) |
|
201 | { |
||
202 | 5 | if ($namespace) { |
|
203 | 1 | $writer->writeAttributeNS($prefix, $name, $namespace, $value); |
|
204 | 1 | } else { |
|
205 | 4 | $writer->writeAttribute($name, $value); |
|
206 | } |
||
207 | 5 | } |
|
208 | |||
209 | /** |
||
210 | * Write an element with namespace if used |
||
211 | * |
||
212 | * @param \XMLWriter $writer XML writer resource |
||
213 | * @param string $prefix Namespace prefix if any |
||
214 | * @param string $name Element name |
||
215 | * @param string $namespace The uri of the namespace |
||
216 | * @param string $value The element content |
||
217 | */ |
||
218 | 15 | protected function writeElement(\XMLWriter $writer, $prefix, $name, $namespace, $value) |
|
219 | { |
||
220 | 15 | if ($namespace) { |
|
221 | 3 | $writer->startElementNS($prefix, $name, $namespace); |
|
222 | 3 | } else { |
|
223 | 12 | $writer->startElement($name); |
|
224 | } |
||
225 | 15 | if (strpbrk($value, '<>&')) { |
|
226 | 1 | $writer->writeCData($value); |
|
227 | 1 | } else { |
|
228 | 14 | $writer->writeRaw($value); |
|
229 | } |
||
230 | 15 | $writer->endElement(); |
|
231 | 15 | } |
|
232 | |||
233 | /** |
||
234 | * Create a new xml writer and start a document |
||
235 | * |
||
236 | * @param string $encoding document encoding |
||
237 | * |
||
238 | * @return \XMLWriter the writer resource |
||
239 | * @throws \RuntimeException if the document cannot be started |
||
240 | */ |
||
241 | 18 | protected function startDocument($encoding) |
|
242 | { |
||
243 | 18 | $this->writer = new \XMLWriter(); |
|
244 | 18 | if (!$this->writer->openMemory()) { |
|
245 | throw new \RuntimeException('Unable to open XML document in memory'); |
||
246 | } |
||
247 | 18 | if (!$this->writer->startDocument('1.0', $encoding)) { |
|
248 | throw new \RuntimeException('Unable to start XML document'); |
||
249 | } |
||
250 | |||
251 | 18 | return $this->writer; |
|
252 | } |
||
253 | |||
254 | /** |
||
255 | * End the document and return the output |
||
256 | * |
||
257 | * @param \XMLWriter $writer |
||
258 | * |
||
259 | * @return string the writer resource |
||
260 | */ |
||
261 | 18 | protected function finishDocument($writer) |
|
262 | { |
||
263 | 18 | $writer->endDocument(); |
|
264 | |||
265 | 18 | return $writer->outputMemory(); |
|
266 | } |
||
267 | |||
268 | /** |
||
269 | * Add an array to the XML |
||
270 | * |
||
271 | * @param \XMLWriter $writer |
||
272 | * @param Parameter $param |
||
273 | * @param $value |
||
274 | */ |
||
275 | 4 | protected function addXmlArray(\XMLWriter $writer, Parameter $param, &$value) |
|
276 | { |
||
277 | 4 | if ($items = $param->getItems()) { |
|
278 | 4 | foreach ($value as $v) { |
|
279 | 4 | $this->addXml($writer, $items, $v); |
|
280 | 4 | } |
|
281 | 4 | } |
|
282 | 4 | } |
|
283 | |||
284 | /** |
||
285 | * Add an object to the XML |
||
286 | * |
||
287 | * @param \XMLWriter $writer |
||
288 | * @param Parameter $param |
||
289 | * @param $value |
||
290 | */ |
||
291 | 8 | protected function addXmlObject(\XMLWriter $writer, Parameter $param, &$value) |
|
292 | { |
||
293 | 8 | $noAttributes = []; |
|
294 | |||
295 | // add values which have attributes |
||
296 | 8 | foreach ($value as $name => $v) { |
|
297 | 8 | if ($property = $param->getProperty($name)) { |
|
0 ignored issues
–
show
Are you sure the assignment to
$property is correct as $param->getProperty($name) (which targets GuzzleHttp\Command\Guzzle\Parameter::getProperty() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
298 | 8 | if ($property->getData('xmlAttribute')) { |
|
299 | 3 | $this->addXml($writer, $property, $v); |
|
300 | 3 | } else { |
|
301 | 7 | $noAttributes[] = ['value' => $v, 'property' => $property]; |
|
302 | } |
||
303 | 8 | } |
|
304 | 8 | } |
|
305 | |||
306 | // now add values with no attributes |
||
307 | 8 | foreach ($noAttributes as $element) { |
|
308 | 7 | $this->addXml($writer, $element['property'], $element['value']); |
|
309 | 8 | } |
|
310 | 8 | } |
|
311 | |||
312 | /** |
||
313 | * @param $value |
||
314 | * @param Parameter $param |
||
315 | * @param Operation $operation |
||
316 | */ |
||
317 | 17 | private function visitWithValue( |
|
318 | $value, |
||
319 | Parameter $param, |
||
320 | Operation $operation |
||
321 | ) { |
||
322 | 17 | if (!$this->writer) { |
|
323 | 17 | $this->createRootElement($operation); |
|
324 | 17 | } |
|
325 | |||
326 | 17 | $this->addXml($this->writer, $param, $value); |
|
327 | 17 | } |
|
328 | } |
||
329 |