Replace Pico::discoverRequestFile() with public Pico::resolveFilePath()

This allows plugins (e.g. PicoAdmin) to safely resolve file paths without the need of re-implementing the method.
This commit is contained in:
Daniel Rudolf 2016-07-20 19:23:19 +02:00
parent e27be7a80f
commit 21bd18bcf0
No known key found for this signature in database
GPG key ID: A061F02CD8DE4538

View file

@ -308,7 +308,7 @@ class Pico
$this->triggerEvent('onRequestUrl', array(&$this->requestUrl));
// discover requested file
$this->discoverRequestFile();
$this->requestFile = $this->resolveFilePath($this->requestUrl);
$this->triggerEvent('onRequestFile', array(&$this->requestFile));
// load raw file content
@ -735,24 +735,29 @@ class Pico
}
/**
* Uses the request URL to discover the content file to serve
* Resolves a given file path to its corresponding content file
*
* This method also prevents `content_dir` breakouts using malicious
* request URLs. We don't use `realpath()`, because we neither want to
* check for file existance, nor prohibit symlinks which intentionally
* point to somewhere outside the `content_dir` folder. It is STRONGLY
* RECOMMENDED to use PHP's `open_basedir` feature - always, not just
* with Pico!
*
* @see Pico::getRequestFile()
* @return void
* @param string $requestUrl path name (likely from a URL) to resolve
* @return string path to the resolved content file
*/
protected function discoverRequestFile()
public function resolveFilePath($requestUrl)
{
$contentDir = $this->getConfig('content_dir');
$contentExt = $this->getConfig('content_ext');
if (empty($this->requestUrl)) {
$this->requestFile = $contentDir . 'index' . $contentExt;
if (empty($requestUrl)) {
return $contentDir . 'index' . $contentExt;
} else {
// prevent content_dir breakouts using malicious request URLs
// we don't use realpath() here because we neither want to check for file existance
// nor prohibit symlinks which intentionally point to somewhere outside the content_dir
// it is STRONGLY RECOMMENDED to use open_basedir - always, not just with Pico!
$requestUrl = str_replace('\\', '/', $this->requestUrl);
// prevent content_dir breakouts
$requestUrl = str_replace('\\', '/', $requestUrl);
$requestUrlParts = explode('/', $requestUrl);
$requestFileParts = array();
@ -768,31 +773,29 @@ class Pico
}
if (empty($requestFileParts)) {
$this->requestFile = $contentDir . 'index' . $contentExt;
return;
return $contentDir . 'index' . $contentExt;
}
// discover the content file to serve
// Note: $requestFileParts neither contains a trailing nor a leading slash
$this->requestFile = $contentDir . implode('/', $requestFileParts);
if (is_dir($this->requestFile)) {
$requestFile = $contentDir . implode('/', $requestFileParts);
if (is_dir($requestFile)) {
// if no index file is found, try a accordingly named file in the previous dir
// if this file doesn't exist either, show the 404 page, but assume the index
// file as being requested (maintains backward compatibility to Pico < 1.0)
$indexFile = $this->requestFile . '/index' . $contentExt;
if (file_exists($indexFile) || !file_exists($this->requestFile . $contentExt)) {
$this->requestFile = $indexFile;
return;
$indexFile = $requestFile . '/index' . $contentExt;
if (file_exists($indexFile) || !file_exists($requestFile . $contentExt)) {
return $indexFile;
}
}
$this->requestFile .= $contentExt;
return $requestFile . $contentExt;
}
}
/**
* Returns the absolute path to the content file to serve
*
* @see Pico::discoverRequestFile()
* @see Pico::resolveFilePath()
* @return string|null file path
*/
public function getRequestFile()