HaaseIT /
HCSF
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); |
||
|
0 ignored issues
–
show
|
|||
| 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); |
||
| 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 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.