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 | namespace Fhp\Response; |
||
4 | |||
5 | use Fhp\Message\AbstractMessage; |
||
6 | use Fhp\Segment\AbstractSegment; |
||
7 | use Fhp\Segment\NameMapping; |
||
8 | |||
9 | /** |
||
10 | * Class Response |
||
11 | * |
||
12 | * @package Fhp\Response |
||
13 | */ |
||
14 | class Response |
||
15 | { |
||
16 | /** @var string */ |
||
17 | public $rawResponse; |
||
18 | |||
19 | /** @var string */ |
||
20 | protected $response; |
||
21 | |||
22 | /** @var array */ |
||
23 | protected $segments = array(); |
||
24 | |||
25 | /** @var string */ |
||
26 | protected $dialogId; |
||
27 | |||
28 | /** @var string */ |
||
29 | protected $systemId; |
||
30 | |||
31 | /** |
||
32 | * Response constructor. |
||
33 | * |
||
34 | * @param string $rawResponse |
||
35 | */ |
||
36 | 1 | public function __construct($rawResponse) |
|
37 | { |
||
38 | 1 | if ($rawResponse instanceof Initialization) { |
|
39 | $rawResponse = $rawResponse->rawResponse; |
||
40 | } |
||
41 | |||
42 | 1 | $this->rawResponse = $rawResponse; |
|
43 | 1 | $this->response = $this->unwrapEncryptedMsg($rawResponse); |
|
44 | 1 | $this->segments = preg_split("#'(?=[A-Z]{4,}:\d|')#", $rawResponse); |
|
45 | 1 | } |
|
46 | |||
47 | /** |
||
48 | * Extracts dialog ID from response. |
||
49 | * |
||
50 | * @return string|null |
||
51 | * @throws \Exception |
||
52 | */ |
||
53 | public function getDialogId() |
||
54 | { |
||
55 | $segment = $this->findSegment('HNHBK'); |
||
56 | |||
57 | if (null === $segment) { |
||
58 | throw new \Exception('Could not find element HNHBK. Invalid response?'); |
||
59 | } |
||
60 | |||
61 | return $this->getSegmentIndex(4, $segment); |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * Extracts bank name from response. |
||
66 | * |
||
67 | * @return string|null |
||
68 | */ |
||
69 | public function getBankName() |
||
70 | { |
||
71 | $bankName = null; |
||
72 | $segment = $this->findSegment('HIBPA'); |
||
73 | if (null != $segment) { |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
74 | $split = $this->splitSegment($segment); |
||
75 | if (isset($split[3])) { |
||
76 | $bankName = $split[3]; |
||
77 | } |
||
78 | } |
||
79 | |||
80 | return $bankName; |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Some kind of HBCI pagination. |
||
85 | * |
||
86 | * @param AbstractMessage $message |
||
87 | * |
||
88 | * @return array |
||
89 | */ |
||
90 | public function getTouchDowns(AbstractMessage $message) |
||
91 | { |
||
92 | $touchdown = array(); |
||
93 | $messageSegments = $message->getEncryptedSegments(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Fhp\Message\AbstractMessage as the method getEncryptedSegments() does only exist in the following sub-classes of Fhp\Message\AbstractMessage : Fhp\Message\Message . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends 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 sub-classes 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.
![]() |
|||
94 | /** @var AbstractSegment $msgSeg */ |
||
95 | foreach ($messageSegments as $msgSeg) { |
||
96 | $segment = $this->findSegmentForReference('HIRMS', $msgSeg); |
||
97 | if (null != $segment) { |
||
0 ignored issues
–
show
|
|||
98 | $parts = $this->splitSegment($segment); |
||
99 | // remove header |
||
100 | array_shift($parts); |
||
101 | foreach ($parts as $p) { |
||
102 | $pSplit = $this->splitDeg($p); |
||
103 | if ($pSplit[0] == 3040) { |
||
104 | $td = $pSplit[3]; |
||
105 | $touchdown[$msgSeg->getName()] = $td; |
||
106 | } |
||
107 | } |
||
108 | } |
||
109 | } |
||
110 | |||
111 | return $touchdown; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * Extracts supported TAN mechanisms from response. |
||
116 | * |
||
117 | * @return array |
||
118 | */ |
||
119 | public function getSupportedTanMechanisms() |
||
120 | { |
||
121 | $segments = $this->findSegments('HIRMS'); |
||
122 | // @todo create method to get reference element from request |
||
123 | foreach ($segments as $segment) { |
||
0 ignored issues
–
show
The expression
$segments of type array|null|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
124 | $segment = $this->splitSegment($segment); |
||
125 | array_shift($segment); |
||
126 | foreach ($segment as $seg) { |
||
127 | list($id, $msg) = explode('::', $seg, 2); |
||
128 | if ("3920" == $id) { |
||
129 | if (preg_match_all('/\d{3}/', $msg, $matches)) { |
||
130 | return $matches[0]; |
||
131 | } |
||
132 | } |
||
133 | } |
||
134 | } |
||
135 | |||
136 | return array(); |
||
137 | } |
||
138 | |||
139 | /** |
||
140 | * @return int |
||
141 | */ |
||
142 | public function getHksalMaxVersion() |
||
143 | { |
||
144 | return $this->getSegmentMaxVersion('HISALS'); |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * @return int |
||
149 | */ |
||
150 | public function getHkkazMaxVersion() |
||
151 | { |
||
152 | return $this->getSegmentMaxVersion('HIKAZS'); |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Checks if request / response was successful. |
||
157 | * |
||
158 | * @return bool |
||
159 | */ |
||
160 | public function isSuccess() |
||
161 | { |
||
162 | $summary = $this->getMessageSummary(); |
||
163 | |||
164 | foreach ($summary as $code => $message) { |
||
165 | if ("9" == substr($code, 0, 1)) { |
||
166 | return false; |
||
167 | } |
||
168 | } |
||
169 | |||
170 | return true; |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * @return array |
||
175 | * @throws \Exception |
||
176 | */ |
||
177 | public function getMessageSummary() |
||
178 | { |
||
179 | return $this->getSummaryBySegment('HIRMG'); |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * @return array |
||
184 | * @throws \Exception |
||
185 | */ |
||
186 | public function getSegmentSummary() |
||
187 | { |
||
188 | return $this->getSummaryBySegment('HIRMS'); |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * @param string $name |
||
193 | * |
||
194 | * @return array |
||
195 | * @throws \Exception |
||
196 | */ |
||
197 | protected function getSummaryBySegment($name) |
||
198 | { |
||
199 | if (!in_array($name, array('HIRMS', 'HIRMG'))) { |
||
200 | throw new \Exception('Invalid segment for message summary. Only HIRMS and HIRMG supported'); |
||
201 | } |
||
202 | |||
203 | $result = array(); |
||
204 | $segment = $this->findSegment($name); |
||
205 | $segment = $this->splitSegment($segment); |
||
206 | array_shift($segment); |
||
207 | foreach ($segment as $de) { |
||
208 | $de = $this->splitDeg($de); |
||
209 | $result[$de[0]] = $de[2]; |
||
210 | } |
||
211 | |||
212 | return $result; |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * @param string $segmentName |
||
217 | * |
||
218 | * @return int |
||
219 | */ |
||
220 | public function getSegmentMaxVersion($segmentName) |
||
221 | { |
||
222 | $version = 3; |
||
223 | $segments = $this->findSegments($segmentName); |
||
224 | foreach ($segments as $s) { |
||
0 ignored issues
–
show
The expression
$segments of type array|null|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
225 | $parts = $this->splitSegment($s); |
||
226 | $segmentHeader = $this->splitDeg($parts[0]); |
||
227 | $curVersion = (int) $segmentHeader[2]; |
||
228 | if ($curVersion > $version) { |
||
229 | $version = $curVersion; |
||
230 | } |
||
231 | } |
||
232 | |||
233 | return $version; |
||
234 | } |
||
235 | |||
236 | /** |
||
237 | * @return string |
||
238 | * @throws \Exception |
||
239 | */ |
||
240 | public function getSystemId() |
||
241 | { |
||
242 | $segment = $this->findSegment('HISYN'); |
||
243 | |||
244 | if (!preg_match('/HISYN:\d+:\d+:\d+\+(.+)/', $segment, $matches)) { |
||
245 | throw new \Exception('Could not determine system id.'); |
||
246 | } |
||
247 | |||
248 | return $matches[1]; |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * @param bool $translateCodes |
||
253 | * |
||
254 | * @return string |
||
255 | */ |
||
256 | View Code Duplication | public function humanReadable($translateCodes = false) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
257 | { |
||
258 | return str_replace( |
||
259 | array("'", '+'), |
||
260 | array(PHP_EOL, PHP_EOL . " "), |
||
261 | $translateCodes |
||
262 | ? NameMapping::translateResponse($this->rawResponse) |
||
263 | : $this->rawResponse |
||
264 | ); |
||
265 | } |
||
266 | |||
267 | /** |
||
268 | * @param string $name |
||
269 | * @param AbstractSegment $reference |
||
270 | * |
||
271 | * @return string|null |
||
272 | */ |
||
273 | protected function findSegmentForReference($name, AbstractSegment $reference) |
||
274 | { |
||
275 | $segments = $this->findSegments($name); |
||
276 | foreach ($segments as $seg) { |
||
0 ignored issues
–
show
The expression
$segments of type array|null|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
277 | $segSplit = $this->splitSegment($seg); |
||
278 | $segSplit = array_shift($segSplit); |
||
279 | $segSplit = $this->splitDeg($segSplit); |
||
280 | if ($segSplit[3] == $reference->getSegmentNumber()) { |
||
281 | return $seg; |
||
282 | } |
||
283 | } |
||
284 | |||
285 | return null; |
||
286 | } |
||
287 | |||
288 | /** |
||
289 | * @param string $name |
||
290 | * |
||
291 | * @return string|null |
||
292 | */ |
||
293 | protected function findSegment($name) |
||
294 | { |
||
295 | return $this->findSegments($name, true); |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * @param string $name |
||
300 | * @param bool $one |
||
301 | * |
||
302 | * @return array|null|string |
||
303 | */ |
||
304 | protected function findSegments($name, $one = false) |
||
305 | { |
||
306 | $found = $one ? null : array(); |
||
307 | |||
308 | foreach ($this->segments as $segment) { |
||
309 | $split = explode(':', $segment, 2); |
||
310 | |||
311 | if ($split[0] == $name) { |
||
312 | if ($one) { |
||
313 | return $segment; |
||
314 | } |
||
315 | $found[] = $segment; |
||
316 | } |
||
317 | } |
||
318 | |||
319 | return $found; |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * @param $segment |
||
324 | * |
||
325 | * @return array |
||
326 | */ |
||
327 | 1 | protected function splitSegment($segment) |
|
328 | { |
||
329 | 1 | $parts = preg_split('/\+(?<!\?\+)/', $segment); |
|
330 | |||
331 | 1 | foreach ($parts as &$part) { |
|
332 | 1 | $part = str_replace('?+', '+', $part); |
|
333 | 1 | } |
|
334 | |||
335 | 1 | return $parts; |
|
336 | } |
||
337 | |||
338 | /** |
||
339 | * @param $deg |
||
340 | * |
||
341 | * @return array |
||
342 | */ |
||
343 | protected function splitDeg($deg) |
||
344 | { |
||
345 | return explode(':', $deg); |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * @param int $idx |
||
350 | * @param $segment |
||
351 | * |
||
352 | * @return string|null |
||
353 | */ |
||
354 | protected function getSegmentIndex($idx, $segment) |
||
355 | { |
||
356 | $segment = $this->splitSegment($segment); |
||
357 | if (isset($segment[$idx - 1])) { |
||
358 | return $segment[$idx - 1]; |
||
359 | } |
||
360 | |||
361 | return null; |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * @param string $response |
||
366 | * |
||
367 | * @return string |
||
368 | */ |
||
369 | 1 | protected function unwrapEncryptedMsg($response) |
|
370 | { |
||
371 | 1 | if (preg_match('/HNVSD:\d+:\d+\+@\d+@(.+)\'\'/', $response, $matches)) { |
|
372 | return $matches[1]; |
||
373 | } |
||
374 | |||
375 | 1 | return $response; |
|
376 | } |
||
377 | } |
||
378 |