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 HaaseIT\HCSF; |
||
4 | |||
5 | use Zend\ServiceManager\ServiceManager; |
||
6 | use Symfony\Component\Yaml\Yaml; |
||
7 | |||
8 | class Router |
||
9 | { |
||
10 | private $P; |
||
11 | |||
12 | /** |
||
13 | * @var string |
||
14 | */ |
||
15 | private $sPath; |
||
16 | |||
17 | /** |
||
18 | * @var ServiceManager |
||
19 | */ |
||
20 | private $serviceManager; |
||
21 | |||
22 | /** |
||
23 | * @var \HaaseIT\HCSF\HelperConfig |
||
24 | */ |
||
25 | protected $config; |
||
26 | |||
27 | /** |
||
28 | * @var \HaaseIT\HCSF\Helper |
||
29 | */ |
||
30 | protected $helper; |
||
31 | |||
32 | /** |
||
33 | * Router constructor. |
||
34 | * @param ServiceManager $serviceManager |
||
35 | */ |
||
36 | public function __construct(ServiceManager $serviceManager) |
||
37 | { |
||
38 | $this->serviceManager = $serviceManager; |
||
39 | $this->config = $serviceManager->get('config'); |
||
40 | $this->helper = $serviceManager->get('helper'); |
||
41 | } |
||
42 | |||
43 | public function getPage() |
||
44 | { |
||
45 | // Maintenance page |
||
46 | if ($this->config->getCore('maintenancemode')) { |
||
47 | try { |
||
48 | $controller = new \HaaseIT\HCSF\Controller\Maintenance($this->serviceManager); |
||
49 | $this->P = $controller->getPage(); |
||
50 | } catch (\Exception $e) { |
||
51 | $this->P = $e->getMessage(); |
||
52 | } |
||
53 | } else { |
||
54 | $routes = require __DIR__.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'routes.php'; |
||
55 | $customRoutesFile = PATH_BASEDIR . 'customization/routes.yml'; |
||
56 | if (is_file($customRoutesFile)) { |
||
57 | try{ |
||
58 | $customRoutes = Yaml::parse(file_get_contents($customRoutesFile)); |
||
59 | View Code Duplication | if (!empty($customRoutes['literal'])) { |
|
60 | $routes['literal'] = array_merge($routes['literal'], $customRoutes['literal']); |
||
61 | } |
||
62 | View Code Duplication | if (!empty($customRoutes['regex'])) { |
|
63 | $routes['regex'] = array_merge($routes['regex'], $customRoutes['regex']); |
||
64 | } |
||
65 | } catch (\Exception $e) { |
||
66 | // todo: log error |
||
67 | } |
||
68 | } |
||
69 | $aURL = parse_url($this->helper->getCleanRequestTarget()); |
||
70 | $this->sPath = $aURL['path']; |
||
71 | |||
72 | $aPath = explode('/', $this->sPath); |
||
73 | if (!empty($routes['literal'][$this->sPath])) { |
||
74 | $class = '\\HaaseIT\\HCSF\\Controller\\'.$routes['literal'][$this->sPath]; |
||
75 | } else { |
||
76 | if (!empty($routes['regex'])) { |
||
77 | foreach ($routes['regex'] as $regex) { |
||
78 | $result = preg_match('(^' . $regex['regex'] . '$)', $this->sPath, $matches); |
||
79 | if ($result) { |
||
80 | $class = '\\HaaseIT\\HCSF\\Controller\\' . $regex['controller']; |
||
81 | break; |
||
82 | } |
||
83 | } |
||
84 | } |
||
85 | if (empty($result) && $aPath[1] === $this->config->getCore('directory_images')) { |
||
86 | $class = Controller\Glide::class; |
||
87 | } |
||
88 | } |
||
89 | |||
90 | if (!empty($class)) { |
||
91 | // Core Page |
||
92 | try { |
||
93 | /** @var Controller\Base $controller */ |
||
94 | $controller = new $class($this->serviceManager, $aPath, (!empty($matches) ? $matches : false)); |
||
95 | $this->P = $controller->getPage(); |
||
96 | } catch (\Exception $e) { |
||
97 | $this->P = new Page(); |
||
98 | // die($e->getMessage()); |
||
99 | $this->P->setStatus(500); |
||
100 | // todo: write error message |
||
101 | //echo $e->getMessage(); |
||
102 | } |
||
103 | } else { |
||
104 | if ($this->config->getCore('enable_module_shop')) { |
||
105 | $aRoutingoverride = $this->getRoutingoverride($aPath); |
||
106 | } |
||
107 | |||
108 | $this->P = new UserPage($this->serviceManager, $this->sPath); |
||
109 | |||
110 | // go and look if the page can be loaded yet |
||
111 | if ($this->P->cb_id === NULL) { |
||
112 | /* |
||
113 | If the last part of the path doesn't include a dot (.) and is not empty, apend a slash. |
||
114 | If there is already a slash at the end, the last part of the path array will be empty. |
||
115 | */ |
||
116 | if (mb_strpos($aPath[count($aPath) - 1], '.') === false && $aPath[count($aPath) - 1] !== '') { |
||
117 | $this->sPath .= '/'; |
||
118 | } |
||
119 | |||
120 | if ($this->sPath[strlen($this->sPath) - 1] === '/') { |
||
121 | $this->sPath .= 'index.html'; |
||
122 | } |
||
123 | |||
124 | $this->P = new UserPage($this->serviceManager, $this->sPath); |
||
125 | } |
||
126 | |||
127 | if ($this->P->cb_id === NULL) { // if the page is still not found, unset the page object |
||
128 | $this->P->setStatus(404); |
||
129 | } else { // if it is found, go on |
||
130 | // Support for shorturls |
||
131 | if ($this->P->cb_pagetype === 'shorturl') { |
||
132 | $this->P->setStatus(302); |
||
133 | $this->P->setHeader('Location', $this->P->cb_pageconfig); |
||
134 | } |
||
135 | |||
136 | if (isset($this->P, $aRoutingoverride) && count($aRoutingoverride)) { |
||
137 | $this->P->cb_pagetype = $aRoutingoverride['cb_pagetype']; |
||
138 | $this->P->cb_pageconfig->itemno = $aRoutingoverride['itemno']; |
||
139 | } |
||
140 | } |
||
141 | } |
||
142 | |||
143 | if ($this->P->getStatus() === 404) { |
||
144 | $this->P = new CorePage($this->serviceManager); |
||
145 | $this->P->cb_pagetype = 'error'; |
||
146 | $this->P->setStatus(404); |
||
147 | $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_page_not_found'); |
||
148 | } elseif ($this->P->getStatus() === 500) { |
||
149 | $this->P = new CorePage($this->serviceManager); |
||
150 | $this->P->cb_pagetype = 'error'; |
||
151 | $this->P->setStatus(500); |
||
152 | $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_server_error'); |
||
153 | } elseif (is_object($this->P) && $this->P->oPayload === null) {// elseif the page has been found but contains no payload... |
||
154 | // no payload is fine if page is one of these |
||
155 | $pagetypesnocontent = [ |
||
156 | 'itemoverviewjson', |
||
157 | 'itemoverview', |
||
158 | 'itemoverviewgrpd', |
||
159 | 'itemdetail', |
||
160 | 'shorturl', |
||
161 | ]; |
||
162 | if (!in_array($this->P->cb_pagetype, $pagetypesnocontent, true)) { |
||
163 | $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_content_not_found'); |
||
164 | $this->P->setStatus(404); |
||
165 | } |
||
166 | } elseif ($this->P->oPayload->cl_lang !== null && $this->P->oPayload->cl_lang !== $this->config->getLang()) { // if the page is available but not in the current language, display info |
||
167 | $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_page_not_available_lang').'<br><br>'.$this->P->oPayload->cl_html; |
||
168 | } |
||
169 | } |
||
170 | return $this->P; |
||
171 | } |
||
172 | |||
173 | private function getRoutingoverride($aPath) |
||
174 | { |
||
175 | $aRoutingoverride = []; |
||
176 | // /xxxx/item/0010.html |
||
177 | $aTMP['parts_in_path'] = count($aPath); |
||
0 ignored issues
–
show
|
|||
178 | // if the last dir in path is 'item' and the last part of the path is not empty |
||
179 | if ($aPath[$aTMP['parts_in_path'] - 2] === 'item' && $aPath[$aTMP['parts_in_path'] - 1] !== '') { |
||
180 | |||
181 | // explode the filename by . |
||
182 | $aTMP['exploded_request_file'] = explode('.', $aPath[$aTMP['parts_in_path'] - 1]); |
||
183 | |||
184 | // if the filename ends in '.html', get the requested itemno |
||
185 | if ($aTMP['exploded_request_file'][count($aTMP['exploded_request_file']) - 1] === 'html') { |
||
186 | // to allow dots in the filename, we have to iterate through all parts of the filename |
||
187 | $aRoutingoverride['itemno'] = ''; |
||
188 | for ($i = 0; $i < count($aTMP['exploded_request_file']) - 1; $i++) { |
||
189 | $aRoutingoverride['itemno'] .= $aTMP['exploded_request_file'][$i].'.'; |
||
190 | } |
||
191 | // remove the trailing dot |
||
192 | $aRoutingoverride['itemno'] = \HaaseIT\Toolbox\Tools::cutStringend($aRoutingoverride['itemno'], 1); |
||
193 | |||
194 | $aRoutingoverride['cb_pagetype'] = 'itemdetail'; |
||
195 | |||
196 | // rebuild the path string without the trailing '/item/itemno.html' |
||
197 | $this->sPath = ''; |
||
198 | for ($i = 0; $i < $aTMP['parts_in_path'] - 2; $i++) { |
||
199 | $this->sPath .= $aPath[$i].'/'; |
||
200 | } |
||
201 | } |
||
202 | } |
||
203 | |||
204 | return $aRoutingoverride; |
||
205 | } |
||
206 | } |
||
207 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArray
is initialized the first time when the foreach loop is entered. You can also see that the value of thebar
key is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.