rss-bridge/lib/utils.php
Dag 2bbce8ebef
refactor: general code base refactor (#2950)
* refactor

* fix: bug in previous refactor

* chore: exclude phpcompat sniff due to bug in phpcompat

* fix: do not leak absolute paths

* refactor/fix: batch extensions checking, fix DOS issue
2022-08-06 22:46:28 +02:00

123 lines
3.2 KiB
PHP

<?php
final class HttpException extends \Exception
{
}
final class Json
{
public static function encode($value): string
{
$flags = JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
return \json_encode($value, $flags);
}
public static function decode(string $json, bool $assoc = true)
{
return \json_decode($json, $assoc, 512, JSON_THROW_ON_ERROR);
}
}
function create_sane_stacktrace(\Throwable $e): array
{
$frames = array_reverse($e->getTrace());
$frames[] = [
'file' => $e->getFile(),
'line' => $e->getLine(),
];
$stackTrace = [];
foreach ($frames as $i => $frame) {
$file = $frame['file'] ?? '(no file)';
$line = $frame['line'] ?? '(no line)';
$stackTrace[] = sprintf(
'#%s %s:%s',
$i,
trim_path_prefix($file),
$line,
);
}
return $stackTrace;
}
/**
* Trim path prefix for privacy/security reasons
*
* Example: "/var/www/rss-bridge/index.php" => "index.php"
*/
function trim_path_prefix(string $filePath): string
{
return mb_substr($filePath, mb_strlen(dirname(__DIR__)) + 1);
}
/**
* This is buggy because strip tags removes a lot that isn't html
*/
function is_html(string $text): bool
{
return strlen(strip_tags($text)) !== strlen($text);
}
/**
* Determines the MIME type from a URL/Path file extension.
*
* _Remarks_:
*
* * The built-in functions `mime_content_type` and `fileinfo` require fetching
* remote contents.
* * A caller can hint for a MIME type by appending `#.ext` to the URL (i.e. `#.image`).
*
* Based on https://stackoverflow.com/a/1147952
*
* @param string $url The URL or path to the file.
* @return string The MIME type of the file.
*/
function parse_mime_type($url)
{
static $mime = null;
if (is_null($mime)) {
// Default values, overriden by /etc/mime.types when present
$mime = [
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'image' => 'image/*',
'mp3' => 'audio/mpeg',
];
// '@' is used to mute open_basedir warning, see issue #818
if (@is_readable('/etc/mime.types')) {
$file = fopen('/etc/mime.types', 'r');
while (($line = fgets($file)) !== false) {
$line = trim(preg_replace('/#.*/', '', $line));
if (!$line) {
continue;
}
$parts = preg_split('/\s+/', $line);
if (count($parts) == 1) {
continue;
}
$type = array_shift($parts);
foreach ($parts as $part) {
$mime[$part] = $type;
}
}
fclose($file);
}
}
if (strpos($url, '?') !== false) {
$url_temp = substr($url, 0, strpos($url, '?'));
if (strpos($url, '#') !== false) {
$anchor = substr($url, strpos($url, '#'));
$url_temp .= $anchor;
}
$url = $url_temp;
}
$ext = strtolower(pathinfo($url, PATHINFO_EXTENSION));
if (!empty($mime[$ext])) {
return $mime[$ext];
}
return 'application/octet-stream';
}