Skip to content

Commit

Permalink
format: Sanitize format name in the format factory
Browse files Browse the repository at this point in the history
RSS-Bridge currently sanitizes the format name only for the display
action, which can cause problems if other actions depend on formats
as well.

It is therefore better to do sanitization in the factory class for
formats. Additionally, formats should not require a perfect match,
so 'Atom' and 'aToM' make no difference. This will also allow users
to define formats in their own style (i.e. only lowercase via CLI).

References #1001
  • Loading branch information
logmanoriginal committed Jun 18, 2019
1 parent 55e1703 commit 1ada9c2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
6 changes: 0 additions & 6 deletions actions/DisplayAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ public function execute() {
$format = $this->userData['format']
or returnClientError('You must specify a format!');

// DEPRECATED: 'nameFormat' scheme is replaced by 'name' in format parameter values
// this is to keep compatibility until futher complete removal
if(($pos = strpos($format, 'Format')) === (strlen($format) - strlen('Format'))) {
$format = substr($format, 0, $pos);
}

// whitelist control
if(!Bridge::isWhitelisted($bridge)) {
throw new \Exception('This bridge is not whitelisted', 401);
Expand Down
53 changes: 52 additions & 1 deletion lib/Format.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static function create($name){
throw new \InvalidArgumentException('Format name invalid!');
}

$name = $name . 'Format';
$name = self::sanitizeFormatName($name) . 'Format';
$pathFormat = self::getWorkingDir() . $name . '.php';

if(!file_exists($pathFormat)) {
Expand Down Expand Up @@ -163,4 +163,55 @@ public static function getFormatNames(){

return $formatNames;
}

/**
* Returns the sanitized format name.
*
* The format name can be specified in various ways:
* * The PHP file name (i.e. `AtomFormat.php`)
* * The PHP file name without file extension (i.e. `AtomFormat`)
* * The format name (i.e. `Atom`)
*
* Casing is ignored (i.e. `ATOM` and `atom` are the same).
*
* A format file matching the given format name must exist in the working
* directory!
*
* @param string $name The format name
* @return string|null The sanitized format name if the provided name is
* valid, null otherwise.
*/
protected static function sanitizeFormatName($name) {

if(is_string($name)) {

// Trim trailing '.php' if exists
if(preg_match('/(.+)(?:\.php)/', $name, $matches)) {
$name = $matches[1];
}

// Trim trailing 'Format' if exists
if(preg_match('/(.+)(?:Format)/i', $name, $matches)) {
$name = $matches[1];
}

// Improve performance for correctly written format names
if(in_array($name, self::getFormatNames())) {
$index = array_search($name, self::getFormatNames());
return self::getFormatNames()[$index];
}

// The name is valid if a corresponding format file is found on disk
if(in_array(strtolower($name), array_map('strtolower', self::getFormatNames()))) {
$index = array_search(strtolower($name), array_map('strtolower', self::getFormatNames()));
return self::getFormatNames()[$index];
}

Debug::log('Invalid format name: "' . $name . '"!');

}

return null; // Bad parameter

}
}

0 comments on commit 1ada9c2

Please sign in to comment.