isDir() && !$entry->isLink()) { rmdir($entry->getPathname()); } else { unlink($entry->getPathname()); } } rmdir($fixture); }); file_put_contents($fixture . '/application/controllers/base.php', 'newInstanceWithoutConstructor(); $uri = (new ReflectionClass('CI_URI'))->newInstanceWithoutConstructor(); $_SERVER['REQUEST_URI'] = '/' . ltrim($path, '/'); $_SERVER['SCRIPT_NAME'] = '/index.php'; $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI']; $detect = new ReflectionMethod('CI_URI', '_detect_uri'); $detect->setAccessible(TRUE); $doc->uri = (object) ['uri_string' => $detect->invoke($uri)]; $doc->load = new class { public $data; public function view($name, $data) { $this->data = $data; } }; return $doc; } function denied($path) { try { $doc = controller($path); $doc->cn(); } catch (RuntimeException $error) { if ($error->getCode() === 404) { check(TRUE, '404 ' . $path); return; } throw $error; } check(FALSE, '404 ' . $path); } // Optional single request for HTTP harnesses, including branches that exit(). if (isset($_GET['route'])) { try { $route = $_GET['route']; $language = strpos($route, '/doc/en/') === 0 ? 'en' : 'cn'; $doc = controller($route); $doc->$language(); echo $doc->load->data['doc']; } catch (RuntimeException $error) { if ($error->getCode() !== 404) { throw $error; } http_response_code(404); echo 'Not found'; } return; } foreach (['cn' => 'zh-cn', 'en' => 'en-us'] as $route => $language) { $doc = controller('/doc/' . $route . '/start/welcome.md'); $doc->$route(); check($doc->load->data['doc'] === 'PUBLIC-' . $language, 'normal ' . $language); } foreach ([ '/doc/cn/....//....//canary.yaml', '/doc/cn/....//....//canary.md', '/doc/cn/....//....//....//....//canary.yaml', '/doc/cn/....//zh-cn-other/canary.md', '/doc/cn/linked.md', '/doc/cn/outside/canary.md', '/doc/cn/local.yaml', '/doc/cn/missing.md', '/doc/cn/' . $image, '/doc/cn/....//....//' . $image, '/doc/cn/..%2f..%2fcanary.yaml', '/doc/cn/empty/', ] as $path) { denied($path); } $doc = controller('/doc/cn/start/welcome.md'); $doc->cn(); $resolve = new ReflectionMethod('Doc', '_resolveDocPath'); $resolve->setAccessible(TRUE); check($resolve->invoke($doc, $fixture . '/doc/zh-cn/start/' . $image) !== FALSE, 'normal image resolves'); check($resolve->invoke($doc, $fixture . '/doc/zh-cn', TRUE) !== FALSE, 'root directory resolves'); check($resolve->invoke($doc, $fixture . '/doc/zh-cn') === FALSE, 'directory cannot be read as a file'); check($resolve->invoke($doc, $fixture . "/doc/zh-cn/start/welcome.md\0") === FALSE, 'NUL rejected'); $menu = new ReflectionMethod('Doc', '_extractMenu'); $menu->setAccessible(TRUE); check($menu->invoke($doc, $fixture . '/canary.md') === [], 'external menu rejected'); check($menu->invoke($doc, $fixture . '/doc/zh-cn/start/index-external.md') === [], 'external menu symlink rejected'); check(count($menu->invoke($doc, $fixture . '/doc/zh-cn/index.md')) === 1, 'normal menu loads'); echo "All documentation path tests passed.\n";