diff --git a/vendor/fatfree/CHANGELOG.md b/vendor/fatfree/CHANGELOG.md index 51d4f70..7a2b1e8 100644 --- a/vendor/fatfree/CHANGELOG.md +++ b/vendor/fatfree/CHANGELOG.md @@ -1,6 +1,51 @@ CHANGELOG +3.9.0 (29.12.2024) +--- +* feat [#377], DB\SQL: check TABLE_SCHEMA in fields introspection query +* feat [#379]: Added `REROUTE_TRAILING_SLASH` to optionally disable rerouting +* feat [#380], Audit: Adding new mac address validation +* fix [#372], Audit: `isprivate()`, `FILTER_FLAG_NO_PRIV_RANGE` usage +* fix [#378]: websocket handlers call +* fix: php 8.4 session handler compatibility +* fix: various php 8.4 warnings +* fix [#382]: PHP 8.4 `E_STRICT` deprecation fix +* fix [#371]: trim string based routes handler +* fix [bcosca/fatfree#1285]: multi-line template tags +* fix [#375]: PHP 8.4 Fixes for implicit nullability deprecation +* fix [#374]: http_build_query usage deprecation fix +* fix [#369]: unify key string replacement for cache getter/setter + +3.8.2 (24.07.2023) +--- +* feat, Base->format: optimize international date formatting for php8.1+ +* fix, Base->format: keep php7 compatibility in date formatter [#360](https://github.com/f3-factory/fatfree-core/issues/360) +* fix, Markdown: unicode chars not captured correctly for headline slugs [#363](https://github.com/f3-factory/fatfree-core/issues/363) +* fix, Preview->resolve: PHP8+ error, undefined variable $hash [#359](https://github.com/f3-factory/fatfree-core/issues/359) +* fix, Base->clean: PHP8+ error, strip_tags with null value usage + +3.8.1 (05.11.2022) +--- +* fix: CORS preflight request fails to find route for ajax-only definitions [bcosca/fatfree#1242](https://github.com/bcosca/fatfree/issues/1242) +* fix: add realpath to captcha font filepath, [#314](https://github.com/bcosca/fatfree-core/issues/314) +* fix: case-insensitive custom tag matching [#353](https://github.com/bcosca/fatfree-core/issues/353) +* fix: php8 error suppression on invalid locale constant access [bcosca/fatfree#1259](https://github.com/bcosca/fatfree/issues/1259) +* fix: iteration over inaccessible object properties, fixes [#350](https://github.com/bcosca/fatfree-core/issues/350) +* feat: let jig handle utf8 issues more gracefully [#352](https://github.com/bcosca/fatfree-core/issues/352) +* fix: BC issue for pre php74 +* fix: ensure template->parse does render zero text-node, [#354](https://github.com/bcosca/fatfree-core/issues/354) +* fix: DB\SQL\Mapper: allow to pass an empty array as $filter, fixes [bcosca/fatfree#1257](https://github.com/bcosca/fatfree/issues/1257) +* fix: adhoc null fields in Twig are executed as callable, [#310](https://github.com/bcosca/fatfree-core/issues/310) +* fix: ensure merged default PARAMS are properly encoded when building alias, [#345](https://github.com/bcosca/fatfree-core/issues/345) +* fix: Added CORS defaults that are not initialized +* fix: SQL cache schema for $fields +* fix: adhoc field with null value php81 issue, [#339](https://github.com/bcosca/fatfree-core/issues/339) +* fix: check against correct identity flags when using IDENTITY_INSERT for sql server +* added missing file location in error handler [bcosca/fatfree#1255](https://github.com/bcosca/fatfree/issues/1255) +* Web->request, add option to adjust accept-encoding in curl engine [#355](https://github.com/bcosca/fatfree-core/issues/355) + 3.8.0 (15 Feb 2022) +--- * Feat: allow access to previous session data in cache-based session handler * Feat: pass session information to onSuspect Session handler * Fix: PHP 8.1 compatibility fixes [#332](https://github.com/bcosca/fatfree-core/issues/332) [#333](https://github.com/bcosca/fatfree-core/issues/333) @@ -13,6 +58,7 @@ CHANGELOG * Fix: trace not present in error handler when in CLI mode and !DEBUG, [#323](https://github.com/bcosca/fatfree-core/issues/323) 3.7.3 (13 Dec 2020) +--- * NEW: added auto_increment detection, [bcosca/fatfree#1192](https://github.com/bcosca/fatfree/issues/1192), [bcosca/fatfree#1093](https://github.com/bcosca/fatfree/issues/1093), [bcosca/fatfree#1175](https://github.com/bcosca/fatfree/issues/1175), [#290](https://github.com/bcosca/fatfree-core/issues/290) * added SMTP dialog error handling, [#317](https://github.com/bcosca/fatfree-core/issues/317) * Fix: Check active transaction before rollback/commit (PHP8 issue) @@ -28,6 +74,7 @@ CHANGELOG * Fixed a couple PHPDOC issues 3.7.2 (28 May 2020) +--- * CHANGED, View->sandbox: disable escaping when rendering as text/plain, [bcosca/fatfree#654](https://github.com/bcosca/fatfree/issues/654) * update HTTP protocol checks, [bcosca/fatfree#1190](https://github.com/bcosca/fatfree/issues/1190) * Base->clear: close vulnerability on variable compilation, [bcosca/fatfree#1191](https://github.com/bcosca/fatfree/issues/1191) @@ -43,12 +90,14 @@ CHANGELOG * only use money_format up until php7.4, [bcosca/fatfree#1174](https://github.com/bcosca/fatfree/issues/1174) 3.7.1 (30. December 2019) +--- * Base->build: Add support for brace-enclosed route tokens * Base->reroute, fix duplicate fragment issue on non-alias routes * DB\SQL\Mapper: fix empty check for pkey when reloading after insert * Web->minify: fix minification with multiple files, [bcosca/fatfree#1152](https://github.com/bcosca/fatfree/issues/1152), [#bcosca/fatfree#1169](https://github.com/bcosca/fatfree/issues/1169) 3.7.0 (26. November 2019) +--- * NEW: Matrix, added select and walk methods for array processing and validation tools * NEW: Added configurable file locking via LOCK var * NEW: json support for dictionary files @@ -84,6 +133,7 @@ CHANGELOG * fix PHPdoc and variable inspection, [bcosca/fatfree#865](https://github.com/bcosca/fatfree/issues/865), [bcosca/fatfree#1128](https://github.com/bcosca/fatfree/issues/1128) 3.6.5 (24 December 2018) +--- * NEW: Log, added timestamp to each line * NEW: Auth, added support for custom compare method, [#116](https://github.com/bcosca/fatfree-core/issues/116) * NEW: cache tag support for mongo & jig mapper, ref [#166](https://github.com/bcosca/fatfree-core/issues/116) @@ -127,6 +177,7 @@ CHANGELOG * Expose Mapper->factory() method 3.6.4 (19 April 2018) +--- * NEW: Added Dependency Injection support with CONTAINER variable [#221](https://github.com/bcosca/fatfree-core/issues/221) * NEW: configurable LOGGABLE error codes [#1091](https://github.com/bcosca/fatfree/issues/1091#issuecomment-364674701) * NEW: JAR.lifetime option, [#178](https://github.com/bcosca/fatfree-core/issues/178) @@ -152,6 +203,7 @@ CHANGELOG * Fixed expiration time when updating an existing cookie 3.6.3 (31 December 2017) +--- * PHP7 fix: remove deprecated (unset) cast * Web->request: restricted follow_location to 3XX responses only * CLI mode: refactored arguments parsing @@ -184,6 +236,7 @@ CHANGELOG * fix View->render using potentially wrong cache entry 3.6.2 (26 June 2017) +--- * Return a status code > 0 when dying on error [#220](https://github.com/bcosca/fatfree-core/issues/220) * fix SMTP line width [#215](https://github.com/bcosca/fatfree-core/issues/215) * Allow using a custom field for ldap user id checking [#217](https://github.com/bcosca/fatfree-core/issues/217) @@ -211,6 +264,7 @@ CHANGELOG * Optimize template conversion to PHP file 3.6.1 (2 April 2017) +--- * NEW: Recaptcha plugin [#194](https://github.com/bcosca/fatfree-core/pull/194) * NEW: MB variable for detecting multibyte support * NEW: DB\SQL: Cache parsed schema for the TTL duration @@ -267,6 +321,7 @@ CHANGELOG * Bug fix: base stripped twice in router (#176) 3.6.0 (19 November 2016) +--- * NEW: [cli] request type * NEW: console-friendly CLI mode * NEW: lexicon caching @@ -375,6 +430,7 @@ CHANGELOG * Bug fix: Trailing slash redirection on UTF-8 paths (#121) 3.5.1 (31 December 2015) +--- * NEW: ttl attribute in template tag * NEW: allow anonymous function for template filter * NEW: format modifier for international and custom currency symbol @@ -422,6 +478,7 @@ CHANGELOG * Bug fix: Web->send() Single quotes around filename not interpreted correctly by some browsers 3.5.0 (2 June 2015) +--- * NEW: until() method for long polling * NEW: abort() to disconnect HTTP client (and continue execution) * NEW: SQL Mapper->required() returns TRUE if field is not nullable @@ -490,6 +547,7 @@ CHANGELOG * Bug fix: ONERROR does not receive PARAMS on fatal error 3.4.0 (1 January 2015) +--- * NEW: [redirects] section * NEW: Custom config sections * NEW: User-defined AUTOLOAD function @@ -552,6 +610,7 @@ CHANGELOG * Bug fix: Undefined pkey (#607) 3.3.0 (8 August 2014) +--- * NEW: Attribute in tag to extend hive * NEW: Image overlay with transparency and alignment control * NEW: Allow redirection of specified route patterns to a URL @@ -583,6 +642,7 @@ CHANGELOG * Quick reference: add RAW variable 3.2.2 (19 March 2014) +--- * NEW: Locales set automatically (Feature request #522) * NEW: Mapper dbtype() * NEW: before- and after- triggers for all mappers @@ -623,6 +683,7 @@ CHANGELOG * Bug fix: BASE is incorrect on Windows 3.2.1 (7 January 2014) +--- * NEW: EMOJI variable, UTF->translate(), UTF->emojify(), and UTF->strrev() * Allow empty strings in config() * Add support for turning off php://input buffering via RAW @@ -649,6 +710,7 @@ CHANGELOG * Bug fix: stringify() recursion 3.2.0 (18 December 2013) +--- * NEW: Automatic CSRF protection (with IP and User-Agent checks) for sessions mapped to SQL-, Jig-, Mongo- and Cache-based backends * NEW: Named routes @@ -718,6 +780,7 @@ CHANGELOG * Bug fix: Loose comparison in stringify() 3.1.2 (5 November 2013) +--- * Abandon .chm help format; Package API documentation in plain HTML; (Launch lib/api/index.html in your browser) * Deprecate BAIL in favor of HALT (default: TRUE) @@ -738,6 +801,7 @@ CHANGELOG * Bug fix: Unknown bcrypt constant 3.1.1 (13 October 2013) +--- * NEW: Support OpenID attribute exchange * NEW: BAIL variable enables/disables continuance of execution on non-fatal errors @@ -765,6 +829,7 @@ CHANGELOG * Bug fix: Calculation of elapsed time 3.1.0 (20 August 2013) +--- * NEW: Web->filler() returns a chunk of text from the standard Lorem Ipsum passage * Change in behavior: Drop support for JSON serialization @@ -793,6 +858,7 @@ CHANGELOG equivalent 3.0.9 (12 June 2013) +--- * NEW: Web->whois() * NEW: Template tags * Improve CACHE consistency @@ -814,6 +880,7 @@ CHANGELOG * Bug fix: Country code constants 3.0.8 (17 May 2013) +--- * NEW: Bcrypt lightweight hashing library\ * Return total number of records in superset in Cursor->paginate() * ONERROR short-circuit (Enhancement #334) @@ -824,6 +891,7 @@ CHANGELOG * Bug fix: Unsupported operand types (Issue #324) 3.0.7 (2 May 2013) +--- * NEW: route() now allows an array of routing patterns as first argument; support array as first argument of map() * NEW: entropy() for calculating password strength (NIST 800-63) @@ -847,6 +915,7 @@ CHANGELOG * Bug fix: Incorrect regex in SMTP 3.0.6 (31 Mar 2013) +--- * NEW: Image->crop() * Modify documentation blocks for PHPDoc interoperability * Allow user to control whether Base->rerouet() uses a permanent or @@ -874,6 +943,7 @@ CHANGELOG * Bug fix: Base->scrub() ignores pass-thru * argument (Issue #274) 3.0.5 (16 Feb 2013) +--- * NEW: Markdown class with PHP, HTML, and .ini syntax highlighting support * NEW: Options for caching of select() and find() results * NEW: Web->acceptable() @@ -897,6 +967,7 @@ CHANGELOG * Bug fix: weather() fails when server is unreachable 3.0.4 (29 Jan 2013) +--- * NEW: Support for ICU/CLDR pluralization * NEW: User-defined FALLBACK language * NEW: minify() now recognizes CSS @import directives @@ -934,6 +1005,7 @@ CHANGELOG * Bug fix: language() return value 3.0.3 (29 Dec 2013) +--- * NEW: [ajax] and [sync] routing pattern modifiers * NEW: Basket class (session-based pseudo-mapper, shopping cart, etc.) * NEW: Test->message() method @@ -965,6 +1037,7 @@ CHANGELOG * Bug fix: URL-decoding 3.0.2 (23 Dec 2013) +--- * NEW: Syntax-highlighted stack traces via Base->highlight(); boolean HIGHLIGHT global variable can be used to enable/disable this feature * NEW: Template engine tag @@ -995,4 +1068,5 @@ CHANGELOG * Use file_get_contents() in methods that don't involve high concurrency 3.0.1 (14 Dec 2013) +--- * Major rewrite of much of the framework's core features diff --git a/vendor/fatfree/audit.php b/vendor/fatfree/audit.php index 26fe349..bf5bd26 100644 --- a/vendor/fatfree/audit.php +++ b/vendor/fatfree/audit.php @@ -77,8 +77,8 @@ class Audit extends Prefab { * @param $addr string **/ function isprivate($addr) { - return !(bool)filter_var($addr,FILTER_VALIDATE_IP, - FILTER_FLAG_IPV4|FILTER_FLAG_IPV6|FILTER_FLAG_NO_PRIV_RANGE); + return (bool)filter_var($addr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6) + && !(bool)filter_var($addr, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE); } /** @@ -189,4 +189,14 @@ class Audit extends Prefab { '/[A-Z].*?[0-9[:punct:]]|[0-9[:punct:]].*?[A-Z]/',$str)); } + /** + * Return TRUE if string is a valid MAC address including EUI-64 format + * @return bool + * @param $addr string + **/ + function mac($addr) { + return (bool)filter_var($addr,FILTER_VALIDATE_MAC) + || preg_match('/^([0-9a-f]{2}:){3}ff:fe(:[0-9a-f]{2}){3}$/i', $addr); + } + } diff --git a/vendor/fatfree/auth.php b/vendor/fatfree/auth.php index a150ce4..4a7e180 100644 --- a/vendor/fatfree/auth.php +++ b/vendor/fatfree/auth.php @@ -247,7 +247,7 @@ class Auth { * @param $args array * @param $func callback **/ - function __construct($storage,array $args=NULL,$func=NULL) { + function __construct($storage,?array $args=NULL,$func=NULL) { if (is_object($storage) && is_a($storage,'DB\Cursor')) { $this->storage=$storage->dbtype(); $this->mapper=$storage; diff --git a/vendor/fatfree/base.php b/vendor/fatfree/base.php index 7c75c79..b406b78 100644 --- a/vendor/fatfree/base.php +++ b/vendor/fatfree/base.php @@ -2,7 +2,7 @@ /* - Copyright (c) 2009-2019 F3::Factory/Bong Cosca, All rights reserved. + Copyright (c) 2009-2023 F3::Factory/Bong Cosca, All rights reserved. This file is part of the Fat-Free Framework (http://fatfreeframework.com). @@ -38,14 +38,88 @@ abstract class Prefab { } } - +/** + * @property string ALIAS + * @property array ALIASES + * @property string|array AUTOLOAD + * @property bool|string CACHE + * @property bool CASELESS + * @property callable|\Prefab|\Psr\Container\ContainerInterface CONTAINER + * @property array COOKIE + * @property array GET + * @property array POST + * @property array REQUEST + * @property array SESSION + * @property array FILES + * @property array SERVER + * @property array ENV + * @property array CORS + * @property int DEBUG + * @property array DIACRITICS + * @property string DNSBL + * @property array EMOJI + * @property string ENCODING + * @property bool ESCAPE + * @property string EXEMPT + * @property object EXCEPTION + * @property string FALLBACK + * @property array FORMATS + * @property string FRAGMENT + * @property bool HALT + * @property bool HIGHLIGHT + * @property array JAR + * @property string LANGUAGE + * @property string LOCALES + * @property string|array LOGGABLE + * @property string LOGS + * @property mixed ONERROR + * @property mixed ONREROUTE + * @property string|null PACKAGE + * @property array PARAMS + * @property string PLUGINS + * @property string PREFIX + * @property string PREMAP + * @property bool QUIET + * @property bool RAW + * @property array ROUTES + * @property string SEED + * @property string SERIALIZER + * @property string TEMP + * @property float TIME + * @property bool REROUTE_TRAILING_SLASH + * @property string TZ + * @property string UI + * @property callback UNLOAD + * @property string UPLOADS + * @property string URI + * @property string VERB + * @property string VERSION + * @property string|null XFRAME + * @property-read string AGENT + * @property-read bool AJAX + * @property-read string BASE + * @property-read string BODY + * @property-read bool CLI + * @property-read array ERROR + * @property-read array HEADERS + * @property-read string HOST + * @property-read string IP + * @property-read string PATH + * @property-read string PATTERN + * @property-read int PORT + * @property-read string QUERY + * @property-read string REALM + * @property-read string RESPONSE + * @property-read string ROOT + * @property-read string SCHEME + */ //! Base structure final class Base extends Prefab implements ArrayAccess { //@{ Framework details const PACKAGE='Fat-Free Framework', - VERSION='3.8.1-Dev'; + VERSION='3.9.0-Release'; //@} //@{ HTTP status codes (RFC 2616) @@ -166,13 +240,17 @@ final class Base extends Prefab implements ArrayAccess { * Replace tokenized URL with available token values * @return string * @param $url array|string + * @param $addParams boolean merge default PARAMS from hive into args * @param $args array **/ - function build($url,$args=[]) { - $args+=$this->hive['PARAMS']; + function build($url, $args=[], $addParams=TRUE) { + if ($addParams) + $args+=$this->recursive($this->hive['PARAMS'], function($val) { + return implode('/', array_map('urlencode', explode('/', $val))); + }); if (is_array($url)) foreach ($url as &$var) { - $var=$this->build($var,$args); + $var=$this->build($var,$args, false); unset($var); } else { @@ -722,7 +800,7 @@ final class Base extends Prefab implements ArrayAccess { * @param $arg mixed * @param $stack array **/ - function stringify($arg,array $stack=NULL) { + function stringify($arg,?array $stack=NULL) { if ($stack) { foreach ($stack as $node) if ($arg===$node) @@ -879,11 +957,15 @@ final class Base extends Prefab implements ArrayAccess { $ref=new ReflectionClass($arg); if ($ref->iscloneable()) { $arg=clone($arg); - $cast=is_a($arg,'IteratorAggregate')? + $cast=($it=is_a($arg,'IteratorAggregate'))? iterator_to_array($arg):get_object_vars($arg); - foreach ($cast as $key=>$val) + foreach ($cast as $key=>$val) { + // skip inaccessible properties #350 + if (!$it && !isset($arg->$key)) + continue; $arg->$key=$this->recursive( $val,$func,array_merge($stack,[$arg])); + } } return $arg; case 'array': @@ -907,7 +989,7 @@ final class Base extends Prefab implements ArrayAccess { return $this->recursive($arg, function($val) use($tags) { if ($tags!='*') - $val=trim(strip_tags($val, + $val=trim(strip_tags($val??'', '<'.implode('><',$this->split($tags)).'>')); return trim(preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F]/','',$val)); @@ -1055,11 +1137,13 @@ final class Base extends Prefab implements ArrayAccess { if ($php81) { $lang = $this->split($this->LANGUAGE); // requires intl extension - $formatter = new IntlDateFormatter($lang[0], - (empty($mod) || $mod=='short') - ? IntlDateFormatter::SHORT : - ($mod=='full' ? IntlDateFormatter::LONG : IntlDateFormatter::MEDIUM), - IntlDateFormatter::NONE); + $dateType=(empty($mod) || $mod=='short') ? IntlDateFormatter::SHORT : + ($mod=='full' ? IntlDateFormatter::FULL : IntlDateFormatter::LONG); + $pattern = $dateType === IntlDateFormatter::SHORT + ? (($ptn=IntlDatePatternGenerator::create($lang[0])) + ? $ptn->getBestPattern('yyyyMMdd') : null) : null; + $formatter = new IntlDateFormatter($lang[0],$dateType, + IntlDateFormatter::NONE, null,null, $pattern); return $formatter->format($args[$pos]); } else { if (empty($mod) || $mod=='short') @@ -1133,10 +1217,12 @@ final class Base extends Prefab implements ArrayAccess { foreach (preg_grep('/^(?!tr)/i',$this->languages) as $locale) { if ($windows) { $parts=explode('-',$locale); - $locale=@constant('ISO::LC_'.$parts[0]); + if (!defined('ISO::LC_'.$parts[0])) + continue; + $locale=constant('ISO::LC_'.$parts[0]); if (isset($parts[1]) && - $country=@constant('ISO::CC_'.strtolower($parts[1]))) - $locale.='-'.$country; + defined($cc='ISO::CC_'.strtolower($parts[1]))) + $locale.='-'.constant($cc); } $locale=str_replace('-','_',$locale); $locales[]=$locale.'.'.ini_get('default_charset'); @@ -1304,7 +1390,7 @@ final class Base extends Prefab implements ArrayAccess { * @param $trace array|NULL * @param $format bool **/ - function trace(array $trace=NULL,$format=TRUE) { + function trace(?array $trace=NULL,$format=TRUE) { if (!$trace) { $trace=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $frame=$trace[0]; @@ -1352,7 +1438,7 @@ final class Base extends Prefab implements ArrayAccess { * @param $trace array * @param $level int **/ - function error($code,$text='',array $trace=NULL,$level=0) { + function error($code,$text='',?array $trace=NULL,$level=0) { $prior=$this->hive['ERROR']; $header=$this->status($code); $req=$this->hive['VERB'].' '.$this->hive['PATH']; @@ -1431,7 +1517,7 @@ final class Base extends Prefab implements ArrayAccess { * @param $body string **/ function mock($pattern, - array $args=NULL,array $headers=NULL,$body=NULL) { + ?array $args=NULL,?array $headers=NULL,$body=NULL) { if (!$args) $args=[]; $types=['sync','ajax','cli']; @@ -1524,7 +1610,7 @@ final class Base extends Prefab implements ArrayAccess { if (!preg_match('/'.self::VERBS.'/',$verb)) $this->error(501,$verb.' '.$this->hive['URI']); $this->hive['ROUTES'][$parts[3]][$type][strtoupper($verb)]= - [$handler,$ttl,$kbps,$alias]; + [is_string($handler) ? trim($handler) : $handler,$ttl,$kbps,$alias]; } } @@ -1710,12 +1796,14 @@ final class Base extends Prefab implements ArrayAccess { $route=NULL; $ptr=$this->hive['CLI']?self::REQ_CLI:$this->hive['AJAX']+1; if (isset($routes[$ptr][$this->hive['VERB']]) || + ($preflight && isset($routes[$ptr])) || isset($routes[$ptr=0])) $route=$routes[$ptr]; if (!$route) continue; if (isset($route[$this->hive['VERB']]) && !$preflight) { - if ($this->hive['VERB']=='GET' && + if ($this->hive['REROUTE_TRAILING_SLASH']===TRUE && + $this->hive['VERB']=='GET' && preg_match('/.+\/$/',$this->hive['PATH'])) $this->reroute(substr($this->hive['PATH'],0,-1). ($this->hive['QUERY']?('?'.$this->hive['QUERY']):'')); @@ -2068,7 +2156,7 @@ final class Base extends Prefab implements ArrayAccess { array_merge([$match['lval']], str_getcsv($cmd[1]=='config'? $this->cast($match['rval']): - $match['rval'])) + $match['rval'],",",'"', "\\")) ); } else { @@ -2091,7 +2179,7 @@ final class Base extends Prefab implements ArrayAccess { // Mark quoted strings with 0x00 whitespace str_getcsv(preg_replace( '/(?[^:]+)(?:\:(?.+))?/', $sec,$parts); @@ -2358,7 +2446,11 @@ final class Base extends Prefab implements ArrayAccess { @ini_set('magic_quotes_gpc',0); @ini_set('register_globals',0); // Intercept errors/exceptions; PHP5.3-compatible - $check=error_reporting((E_ALL|E_STRICT)&~(E_NOTICE|E_USER_NOTICE)); + if (PHP_VERSION_ID >= 80400) { + $check = error_reporting((E_ALL) & ~(E_NOTICE | E_USER_NOTICE)); + } else { + $check = error_reporting((E_ALL | E_STRICT) & ~(E_NOTICE | E_USER_NOTICE)); + } set_exception_handler( function($obj) { /** @var Exception $obj */ @@ -2371,8 +2463,11 @@ final class Base extends Prefab implements ArrayAccess { ); set_error_handler( function($level,$text,$file,$line) { - if ($level & error_reporting()) - $this->error(500,$text,NULL,$level); + if ($level & error_reporting()) { + $trace=$this->trace(null, false); + array_unshift($trace,['file'=>$file,'line'=>$line]); + $this->error(500,$text,$trace,$level); + } } ); if (!isset($_SERVER['SERVER_NAME']) || $_SERVER['SERVER_NAME']==='') @@ -2483,13 +2578,7 @@ final class Base extends Prefab implements ArrayAccess { 'CACHE'=>FALSE, 'CASELESS'=>TRUE, 'CLI'=>$cli, - 'CORS'=>[ - 'headers'=>'', - 'origin'=>FALSE, - 'credentials'=>FALSE, - 'expose'=>FALSE, - 'ttl'=>0 - ], + 'CORS'=>[], 'DEBUG'=>0, 'DIACRITICS'=>[], 'DNSBL'=>'', @@ -2520,6 +2609,7 @@ final class Base extends Prefab implements ArrayAccess { 'PACKAGE'=>self::PACKAGE, 'PARAMS'=>[], 'PATH'=>$path, + 'REROUTE_TRAILING_SLASH'=>TRUE, 'PATTERN'=>NULL, 'PLUGINS'=>$this->fixslashes(__DIR__).'/', 'PORT'=>$port, @@ -2548,6 +2638,13 @@ final class Base extends Prefab implements ArrayAccess { 'VERSION'=>self::VERSION, 'XFRAME'=>'SAMEORIGIN' ]; + $this->hive['CORS']+=[ + 'headers'=>'', + 'origin'=>FALSE, + 'credentials'=>FALSE, + 'expose'=>FALSE, + 'ttl'=>0 + ]; if (!headers_sent() && session_status()!=PHP_SESSION_ACTIVE) { unset($jar['expire']); session_cache_limiter(''); @@ -2631,7 +2728,8 @@ class Cache extends Prefab { $raw=xcache_get($ndx); break; case 'folder': - $raw=$fw->read($parts[1].$ndx); + $raw=$fw->read($parts[1] + .str_replace(['/','\\'],'',$ndx)); break; } if (!empty($raw)) { @@ -2911,7 +3009,7 @@ class View extends Prefab { * @param $hive array * @param $mime string **/ - protected function sandbox(array $hive=NULL,$mime=NULL) { + protected function sandbox(?array $hive=NULL,$mime=NULL) { $fw=$this->fw; $implicit=FALSE; if (is_null($hive)) { @@ -2948,7 +3046,7 @@ class View extends Prefab { * @param $hive array * @param $ttl int **/ - function render($file,$mime='text/html',array $hive=NULL,$ttl=0) { + function render($file,$mime='text/html',?array $hive=NULL,$ttl=0) { $fw=$this->fw; $cache=Cache::instance(); foreach ($fw->split($fw->UI) as $dir) { @@ -3095,7 +3193,8 @@ class Preview extends View { * @param $persist bool * @param $escape bool **/ - function resolve($node,array $hive=NULL,$ttl=0,$persist=FALSE,$escape=NULL) { + function resolve($node,?array $hive=NULL,$ttl=0,$persist=FALSE,$escape=NULL) { + $hash=null; $fw=$this->fw; $cache=Cache::instance(); if ($escape!==NULL) { @@ -3156,7 +3255,7 @@ class Preview extends View { * @param $hive array * @param $ttl int **/ - function render($file,$mime='text/html',array $hive=NULL,$ttl=0) { + function render($file,$mime='text/html',?array $hive=NULL,$ttl=0) { $fw=$this->fw; $cache=Cache::instance(); if (!is_dir($tmp=$fw->TEMP)) diff --git a/vendor/fatfree/cli/ws.php b/vendor/fatfree/cli/ws.php index 4545e9b..ef1a06b 100644 --- a/vendor/fatfree/cli/ws.php +++ b/vendor/fatfree/cli/ws.php @@ -399,8 +399,8 @@ class Agent { if (is_bool($server->write($this->socket,$buf))) return FALSE; if (!in_array($op,[WS::Pong,WS::Close]) && - isset($this->server->events['send']) && - is_callable($func=$this->server->events['send'])) + isset($this->server->events()['send']) && + is_callable($func=$this->server->events()['send'])) $func($this,$op,$data); return $data; } @@ -446,8 +446,8 @@ class Agent { case WS::Text: $data=trim($data); case WS::Binary: - if (isset($this->server->events['receive']) && - is_callable($func=$this->server->events['receive'])) + if (isset($this->server->events()['receive']) && + is_callable($func=$this->server->events()['receive'])) $func($this,$op,$data); break; } @@ -459,8 +459,8 @@ class Agent { * Destroy object **/ function __destruct() { - if (isset($this->server->events['disconnect']) && - is_callable($func=$this->server->events['disconnect'])) + if (isset($this->server->events()['disconnect']) && + is_callable($func=$this->server->events()['disconnect'])) $func($this); } @@ -479,8 +479,8 @@ class Agent { $this->uri=$uri; $this->headers=$hdrs; - if (isset($server->events['connect']) && - is_callable($func=$server->events['connect'])) + if (isset($server->events()['connect']) && + is_callable($func=$server->events()['connect'])) $func($this); } diff --git a/vendor/fatfree/composer.json b/vendor/fatfree/composer.json index 01bdca1..45635d2 100644 --- a/vendor/fatfree/composer.json +++ b/vendor/fatfree/composer.json @@ -4,7 +4,7 @@ "homepage": "http://fatfreeframework.com/", "license": "GPL-3.0", "require": { - "php": ">=5.4" + "php": ">=7.2" }, "autoload": { "classmap": ["."] diff --git a/vendor/fatfree/db/cursor.php b/vendor/fatfree/db/cursor.php index 266a143..e692ac1 100644 --- a/vendor/fatfree/db/cursor.php +++ b/vendor/fatfree/db/cursor.php @@ -64,7 +64,7 @@ abstract class Cursor extends \Magic implements \IteratorAggregate { * @param $options array * @param $ttl int **/ - abstract function find($filter=NULL,array $options=NULL,$ttl=0); + abstract function find($filter=NULL,?array $options=NULL,$ttl=0); /** * Count records that match criteria @@ -73,7 +73,7 @@ abstract class Cursor extends \Magic implements \IteratorAggregate { * @param $options array * @param $ttl int **/ - abstract function count($filter=NULL,array $options=NULL,$ttl=0); + abstract function count($filter=NULL,?array $options=NULL,$ttl=0); /** * Insert new record @@ -126,7 +126,7 @@ abstract class Cursor extends \Magic implements \IteratorAggregate { * @param $options array * @param $ttl int **/ - function findone($filter=NULL,array $options=NULL,$ttl=0) { + function findone($filter=NULL,?array $options=NULL,$ttl=0) { if (!$options) $options=[]; // Override limit @@ -147,7 +147,7 @@ abstract class Cursor extends \Magic implements \IteratorAggregate { * @param $bounce bool **/ function paginate( - $pos=0,$size=10,$filter=NULL,array $options=NULL,$ttl=0,$bounce=TRUE) { + $pos=0,$size=10,$filter=NULL,?array $options=NULL,$ttl=0,$bounce=TRUE) { $total=$this->count($filter,$options,$ttl); $count=(int)ceil($total/$size); if ($bounce) @@ -169,12 +169,12 @@ abstract class Cursor extends \Magic implements \IteratorAggregate { /** * Map to first record that matches criteria - * @return array|FALSE + * @return \DB\SQL\Mapper|FALSE * @param $filter string|array * @param $options array * @param $ttl int **/ - function load($filter=NULL,array $options=NULL,$ttl=0) { + function load($filter=NULL,?array $options=NULL,$ttl=0) { $this->reset(); return ($this->query=$this->find($filter,$options,$ttl)) && $this->skip(0)?$this->query[$this->ptr]:FALSE; diff --git a/vendor/fatfree/db/jig.php b/vendor/fatfree/db/jig.php index bcc29ca..ab2b67f 100644 --- a/vendor/fatfree/db/jig.php +++ b/vendor/fatfree/db/jig.php @@ -78,13 +78,16 @@ class Jig { * @param $file string * @param $data array **/ - function write($file,array $data=NULL) { + function write($file,?array $data=NULL) { if (!$this->dir || $this->lazy) return count($this->data[$file]=$data); $fw=\Base::instance(); switch ($this->format) { case self::FORMAT_JSON: - $out=json_encode($data,JSON_PRETTY_PRINT); + if(version_compare(PHP_VERSION, '7.2.0') >= 0) + $out=json_encode($data,JSON_PRETTY_PRINT | JSON_INVALID_UTF8_IGNORE); + else + $out=json_encode($data,JSON_PRETTY_PRINT | JSON_PARTIAL_OUTPUT_ON_ERROR); break; case self::FORMAT_Serialized: $out=$fw->serialize($data); diff --git a/vendor/fatfree/db/jig/mapper.php b/vendor/fatfree/db/jig/mapper.php index 8f4af54..c640554 100644 --- a/vendor/fatfree/db/jig/mapper.php +++ b/vendor/fatfree/db/jig/mapper.php @@ -156,7 +156,7 @@ class Mapper extends \DB\Cursor { * @param $ttl int|array * @param $log bool **/ - function find($filter=NULL,array $options=NULL,$ttl=0,$log=TRUE) { + function find($filter=NULL,?array $options=NULL,$ttl=0,$log=TRUE) { if (!$options) $options=[]; $options+=[ @@ -352,7 +352,7 @@ class Mapper extends \DB\Cursor { * @param $options array * @param $ttl int|array **/ - function count($filter=NULL,array $options=NULL,$ttl=0) { + function count($filter=NULL,?array $options=NULL,$ttl=0) { $now=microtime(TRUE); $out=count($this->find($filter,$options,$ttl,FALSE)); $this->db->jot('('.sprintf('%.1f',1e3*(microtime(TRUE)-$now)).'ms) '. diff --git a/vendor/fatfree/db/jig/session.php b/vendor/fatfree/db/jig/session.php index eee1339..20f509b 100644 --- a/vendor/fatfree/db/jig/session.php +++ b/vendor/fatfree/db/jig/session.php @@ -22,6 +22,9 @@ namespace DB\Jig; +use ReturnTypeWillChange; +use SessionAdapter; + //! Jig-managed session handler class Session extends Mapper { @@ -43,15 +46,17 @@ class Session extends Mapper { * @param $path string * @param $name string **/ - function open($path,$name) { - return TRUE; - } + function open(string $path, string $name): bool + { + return TRUE; + } /** * Close session * @return TRUE **/ - function close() { + function close(): bool + { $this->reset(); $this->sid=NULL; return TRUE; @@ -59,10 +64,12 @@ class Session extends Mapper { /** * Return session data in serialized format - * @return string + * @return string|false * @param $id string **/ - function read($id) { + #[ReturnTypeWillChange] + function read($id) + { $this->load(['@session_id=?',$this->sid=$id]); if ($this->dry()) return ''; @@ -87,7 +94,8 @@ class Session extends Mapper { * @param $id string * @param $data string **/ - function write($id,$data) { + function write(string $id, string $data): bool + { $this->set('session_id',$id); $this->set('data',$data); $this->set('ip',$this->_ip); @@ -102,19 +110,19 @@ class Session extends Mapper { * @return TRUE * @param $id string **/ - function destroy($id) { + function destroy($id): bool + { $this->erase(['@session_id=?',$id]); return TRUE; } /** * Garbage collector - * @return TRUE - * @param $max int **/ - function cleanup($max) { - $this->erase(['@stamp+?erase(['@stamp+?onsuspect=$onsuspect; - session_set_save_handler( - [$this,'open'], - [$this,'close'], - [$this,'read'], - [$this,'write'], - [$this,'destroy'], - [$this,'cleanup'] - ); + if (version_compare(PHP_VERSION, '8.4.0')>=0) { + // TODO: remove this when php7 support is dropped + session_set_save_handler(new SessionAdapter($this)); + } else { + session_set_save_handler( + [$this,'open'], + [$this,'close'], + [$this,'read'], + [$this,'write'], + [$this,'destroy'], + [$this,'gc'] + ); + } register_shutdown_function('session_commit'); $fw=\Base::instance(); $headers=$fw->HEADERS; diff --git a/vendor/fatfree/db/mongo.php b/vendor/fatfree/db/mongo.php index 46d00be..7b6ba92 100644 --- a/vendor/fatfree/db/mongo.php +++ b/vendor/fatfree/db/mongo.php @@ -130,7 +130,7 @@ class Mongo { * @param $dbname string * @param $options array **/ - function __construct($dsn,$dbname,array $options=NULL) { + function __construct($dsn,$dbname,?array $options=NULL) { $this->uuid=\Base::instance()->hash($this->dsn=$dsn); if ($this->legacy=class_exists('\MongoClient')) { $this->db=new \MongoDB(new \MongoClient($dsn,$options?:[]),$dbname); diff --git a/vendor/fatfree/db/mongo/mapper.php b/vendor/fatfree/db/mongo/mapper.php index 71de62c..a70b6a1 100644 --- a/vendor/fatfree/db/mongo/mapper.php +++ b/vendor/fatfree/db/mongo/mapper.php @@ -121,7 +121,7 @@ class Mapper extends \DB\Cursor { * @param $options array * @param $ttl int|array **/ - function select($fields=NULL,$filter=NULL,array $options=NULL,$ttl=0) { + function select($fields=NULL,$filter=NULL,?array $options=NULL,$ttl=0) { if (!$options) $options=[]; $options+=[ @@ -199,7 +199,7 @@ class Mapper extends \DB\Cursor { * @param $options array * @param $ttl int|array **/ - function find($filter=NULL,array $options=NULL,$ttl=0) { + function find($filter=NULL,?array $options=NULL,$ttl=0) { if (!$options) $options=[]; $options+=[ @@ -218,7 +218,7 @@ class Mapper extends \DB\Cursor { * @param $options array * @param $ttl int|array **/ - function count($filter=NULL,array $options=NULL,$ttl=0) { + function count($filter=NULL,?array $options=NULL,$ttl=0) { $fw=\Base::instance(); $cache=\Cache::instance(); $tag=''; diff --git a/vendor/fatfree/db/mongo/session.php b/vendor/fatfree/db/mongo/session.php index 013f171..f41f171 100644 --- a/vendor/fatfree/db/mongo/session.php +++ b/vendor/fatfree/db/mongo/session.php @@ -22,6 +22,9 @@ namespace DB\Mongo; +use ReturnTypeWillChange; +use SessionAdapter; + //! MongoDB-managed session handler class Session extends Mapper { @@ -43,7 +46,8 @@ class Session extends Mapper { * @param $path string * @param $name string **/ - function open($path,$name) { + function open(string $path, string $name): bool + { return TRUE; } @@ -51,7 +55,8 @@ class Session extends Mapper { * Close session * @return TRUE **/ - function close() { + function close(): bool + { $this->reset(); $this->sid=NULL; return TRUE; @@ -62,7 +67,9 @@ class Session extends Mapper { * @return string * @param $id string **/ - function read($id) { + #[ReturnTypeWillChange] + function read(string $id) + { $this->load(['session_id'=>$this->sid=$id]); if ($this->dry()) return ''; @@ -87,7 +94,8 @@ class Session extends Mapper { * @param $id string * @param $data string **/ - function write($id,$data) { + function write(string $id, string $data): bool + { $this->set('session_id',$id); $this->set('data',$data); $this->set('ip',$this->_ip); @@ -102,19 +110,19 @@ class Session extends Mapper { * @return TRUE * @param $id string **/ - function destroy($id) { + function destroy($id): bool + { $this->erase(['session_id'=>$id]); return TRUE; } /** * Garbage collector - * @return TRUE - * @param $max int **/ - function cleanup($max) { - $this->erase(['$where'=>'this.stamp+'.$max.'<'.time()]); - return TRUE; + #[ReturnTypeWillChange] + function gc(int $max_lifetime): int + { + return (int) $this->erase(['$where'=>'this.stamp+'.$max_lifetime.'<'.time()]); } /** @@ -169,14 +177,19 @@ class Session extends Mapper { function __construct(\DB\Mongo $db,$table='sessions',$onsuspect=NULL,$key=NULL) { parent::__construct($db,$table); $this->onsuspect=$onsuspect; - session_set_save_handler( - [$this,'open'], - [$this,'close'], - [$this,'read'], - [$this,'write'], - [$this,'destroy'], - [$this,'cleanup'] - ); + if (version_compare(PHP_VERSION, '8.4.0')>=0) { + // TODO: remove this when php7 support is dropped + session_set_save_handler(new SessionAdapter($this)); + } else { + session_set_save_handler( + [$this,'open'], + [$this,'close'], + [$this,'read'], + [$this,'write'], + [$this,'destroy'], + [$this,'gc'] + ); + } register_shutdown_function('session_commit'); $fw=\Base::instance(); $headers=$fw->HEADERS; diff --git a/vendor/fatfree/db/sql.php b/vendor/fatfree/db/sql.php index 4c5cc44..780edb2 100644 --- a/vendor/fatfree/db/sql.php +++ b/vendor/fatfree/db/sql.php @@ -124,8 +124,8 @@ class SQL { function value($type,$val) { switch ($type) { case self::PARAM_FLOAT: - if (!is_string($val)) - $val=str_replace(',','.',$val); + if (!is_string($val) && $val !== NULL) + $val=str_replace(',','.',(string) $val); return $val; case \PDO::PARAM_NULL: return NULL; @@ -319,7 +319,7 @@ class SQL { $cache=\Cache::instance(); if ($fw->CACHE && $ttl && ($cached=$cache->exists( - $hash=$fw->hash($this->dsn.$table).'.schema',$result)) && + $hash=$fw->hash($this->dsn.$table.(is_array($fields) ? implode(',',$fields) : $fields)).'.schema',$result)) && $cached[0]+$ttl>microtime(TRUE)) return $result; if (strpos($table,'.')) @@ -375,6 +375,7 @@ class SQL { ('AND K.TABLE_CATALOG=T.TABLE_CATALOG '):''). 'WHERE '. 'C.TABLE_NAME='.$this->quote($table). + (empty($schema) ? '' : ' AND C.TABLE_SCHEMA='.$this->quote($schema)). ($this->dbname? (' AND C.TABLE_CATALOG='. $this->quote($this->dbname)):''), @@ -535,7 +536,7 @@ class SQL { * @param $pw string * @param $options array **/ - function __construct($dsn,$user=NULL,$pw=NULL,array $options=NULL) { + function __construct($dsn,$user=NULL,$pw=NULL,?array $options=NULL) { $fw=\Base::instance(); $this->uuid=$fw->hash($this->dsn=$dsn); if (preg_match('/^.+?(?:dbname|database)=(.+?)(?=;|$)/is',$dsn,$parts)) diff --git a/vendor/fatfree/db/sql/mapper.php b/vendor/fatfree/db/sql/mapper.php index 52c8096..9273eba 100644 --- a/vendor/fatfree/db/sql/mapper.php +++ b/vendor/fatfree/db/sql/mapper.php @@ -149,13 +149,11 @@ class Mapper extends \DB\Cursor { * @return mixed * @param $func string * @param $args array + * @deprecated (this is only used for custom dynamic properties that are callables **/ function __call($func,$args) { - return call_user_func_array( - (array_key_exists($func,$this->props)? - $this->props[$func]: - $this->$func),$args - ); + $callable = (array_key_exists($func,$this->props) ? $this->props[$func] : $this->$func); + return $callable ? call_user_func_array($callable,$args) : null; } /** @@ -207,7 +205,7 @@ class Mapper extends \DB\Cursor { * @param $filter string|array * @param $options array **/ - function stringify($fields,$filter=NULL,array $options=NULL) { + function stringify($fields,$filter=NULL,?array $options=NULL) { if (!$options) $options=[]; $options+=[ @@ -222,7 +220,7 @@ class Mapper extends \DB\Cursor { if (isset($this->as)) $sql.=' AS '.$this->db->quotekey($this->as); $args=[]; - if (is_array($filter)) { + if (is_array($filter) && !empty($filter)) { $args=isset($filter[1]) && is_array($filter[1])? $filter[1]: array_slice($filter,1,NULL,TRUE); @@ -305,7 +303,7 @@ class Mapper extends \DB\Cursor { * @param $options array * @param $ttl int|array **/ - function select($fields,$filter=NULL,array $options=NULL,$ttl=0) { + function select($fields,$filter=NULL,?array $options=NULL,$ttl=0) { list($sql,$args)=$this->stringify($fields,$filter,$options); $result=$this->db->exec($sql,$args,$ttl); $out=[]; @@ -331,7 +329,7 @@ class Mapper extends \DB\Cursor { * @param $options array * @param $ttl int|array **/ - function find($filter=NULL,array $options=NULL,$ttl=0) { + function find($filter=NULL,?array $options=NULL,$ttl=0) { if (!$options) $options=[]; $options+=[ @@ -357,7 +355,7 @@ class Mapper extends \DB\Cursor { * @param $options array * @param $ttl int|array **/ - function count($filter=NULL,array $options=NULL,$ttl=0) { + function count($filter=NULL,?array $options=NULL,$ttl=0) { $adhoc=[]; // with grouping involved, we need to wrap the actualy query and count the results if ($subquery_mode=($options && !empty($options['group']))) { diff --git a/vendor/fatfree/db/sql/session.php b/vendor/fatfree/db/sql/session.php index 8defbf4..45c7137 100644 --- a/vendor/fatfree/db/sql/session.php +++ b/vendor/fatfree/db/sql/session.php @@ -22,6 +22,9 @@ namespace DB\SQL; +use ReturnTypeWillChange; +use SessionAdapter; + //! SQL-managed session handler class Session extends Mapper { @@ -43,7 +46,8 @@ class Session extends Mapper { * @param $path string * @param $name string **/ - function open($path,$name) { + function open(string $path, string $name): bool + { return TRUE; } @@ -51,7 +55,8 @@ class Session extends Mapper { * Close session * @return TRUE **/ - function close() { + function close(): bool + { $this->reset(); $this->sid=NULL; return TRUE; @@ -59,10 +64,12 @@ class Session extends Mapper { /** * Return session data in serialized format - * @return string + * @return string|false * @param $id string **/ - function read($id) { + #[ReturnTypeWillChange] + function read(string $id) + { $this->load(['session_id=?',$this->sid=$id]); if ($this->dry()) return ''; @@ -86,7 +93,8 @@ class Session extends Mapper { * @param $id string * @param $data string **/ - function write($id,$data) { + function write(string $id, string $data): bool + { $this->set('session_id',$id); $this->set('data',$data); $this->set('ip',$this->_ip); @@ -101,19 +109,19 @@ class Session extends Mapper { * @return TRUE * @param $id string **/ - function destroy($id) { + function destroy($id): bool + { $this->erase(['session_id=?',$id]); return TRUE; } /** * Garbage collector - * @return TRUE - * @param $max int **/ - function cleanup($max) { - $this->erase(['stamp+?erase(['stamp+?onsuspect=$onsuspect; - session_set_save_handler( - [$this,'open'], - [$this,'close'], - [$this,'read'], - [$this,'write'], - [$this,'destroy'], - [$this,'cleanup'] - ); + if (version_compare(PHP_VERSION, '8.4.0')>=0) { + // TODO: remove this when php7 support is dropped + session_set_save_handler(new SessionAdapter($this)); + } else { + session_set_save_handler( + [$this,'open'], + [$this,'close'], + [$this,'read'], + [$this,'write'], + [$this,'destroy'], + [$this,'gc'] + ); + } register_shutdown_function('session_commit'); $fw=\Base::instance(); $headers=$fw->HEADERS; diff --git a/vendor/fatfree/image.php b/vendor/fatfree/image.php index 367ca6e..850bf8f 100644 --- a/vendor/fatfree/image.php +++ b/vendor/fatfree/image.php @@ -414,7 +414,7 @@ class Image { } $fw=Base::instance(); foreach ($fw->split($path?:$fw->UI.';./') as $dir) - if (is_file($path=$dir.$font)) { + if (is_file($path=realpath($dir.$font))) { $seed=strtoupper(substr( $ssl?bin2hex(openssl_random_pseudo_bytes($len)):uniqid(), -$len)); diff --git a/vendor/fatfree/markdown.php b/vendor/fatfree/markdown.php index 4be4c56..cb03d14 100644 --- a/vendor/fatfree/markdown.php +++ b/vendor/fatfree/markdown.php @@ -467,8 +467,8 @@ class Markdown extends Prefab { 'fence'=>'/^`{3}\h*(\w+)?.*?[^\n]*\n+(.+?)`{3}[^\n]*'. '(?:\n+|$)/s', 'hr'=>'/^\h*[*_\-](?:\h?[\*_\-]){2,}\h*(?:\n+|$)/', - 'atx'=>'/^\h*(#{1,6})\h?(.+?)\h*(?:#.*)?(?:\n+|$)/', - 'setext'=>'/^\h*(.+?)\h*\n([=\-])+\h*(?:\n+|$)/', + 'atx'=>'/^\h*(#{1,6})\h?(.+?)\h*(?:#.*)?(?:\n+|$)/u', + 'setext'=>'/^\h*(.+?)\h*\n([=\-])+\h*(?:\n+|$)/u', 'li'=>'/^(?:(?:[*+\-]|\d+\.)\h.+?(?:\n+|$)'. '(?:(?: {4}|\t)+.+?(?:\n+|$))*)+/s', 'raw'=>'/^((?:|'. diff --git a/vendor/fatfree/session.php b/vendor/fatfree/session.php index 9e8d600..e4eb82a 100644 --- a/vendor/fatfree/session.php +++ b/vendor/fatfree/session.php @@ -45,7 +45,8 @@ class Session extends Magic { * @param $path string * @param $name string **/ - function open($path,$name) { + function open(string $path, string $name): bool + { return TRUE; } @@ -53,7 +54,8 @@ class Session extends Magic { * Close session * @return TRUE **/ - function close() { + function close(): bool + { $this->sid=NULL; $this->_data=[]; return TRUE; @@ -61,10 +63,12 @@ class Session extends Magic { /** * Return session data in serialized format - * @return string + * @return false|string * @param $id string **/ - function read($id) { + #[ReturnTypeWillChange] + function read(string $id) + { $this->sid=$id; if (!$data=$this->_cache->get($id.'.@')) return ''; @@ -85,11 +89,9 @@ class Session extends Magic { /** * Write session data - * @return TRUE - * @param $id string - * @param $data string - **/ - function write($id,$data) { + */ + function write(string $id, string $data): bool + { $fw=Base::instance(); $jar=$fw->JAR; $this->_cache->set($id.'.@', @@ -106,21 +108,20 @@ class Session extends Magic { /** * Destroy session - * @return TRUE - * @param $id string - **/ - function destroy($id) { + */ + function destroy(string $id): bool + { $this->_cache->clear($id.'.@'); return TRUE; } /** * Garbage collector - * @return TRUE - * @param $max int **/ - function cleanup($max) { - $this->_cache->reset('.@',$max); + #[ReturnTypeWillChange] + function gc(int $max_lifetime) + { + $this->_cache->reset('.@',$max_lifetime); return TRUE; } @@ -175,14 +176,19 @@ class Session extends Magic { function __construct($onsuspect=NULL,$key=NULL,$cache=null) { $this->onsuspect=$onsuspect; $this->_cache=$cache?:Cache::instance(); - session_set_save_handler( - [$this,'open'], - [$this,'close'], - [$this,'read'], - [$this,'write'], - [$this,'destroy'], - [$this,'cleanup'] - ); + if (version_compare(PHP_VERSION, '8.4.0')>=0) { + // TODO: remove this when php7 support is dropped + session_set_save_handler(new SessionAdapter($this)); + } else { + session_set_save_handler( + [$this,'open'], + [$this,'close'], + [$this,'read'], + [$this,'write'], + [$this,'destroy'], + [$this,'gc'] + ); + } register_shutdown_function('session_commit'); $fw=\Base::instance(); $headers=$fw->HEADERS; diff --git a/vendor/fatfree/sessionadapter.php b/vendor/fatfree/sessionadapter.php new file mode 100644 index 0000000..8713118 --- /dev/null +++ b/vendor/fatfree/sessionadapter.php @@ -0,0 +1,46 @@ +_handler = $handler; + } + + public function close(): bool + { + return $this->_handler->close(); + } + + public function destroy(string $id): bool + { + return $this->_handler->destroy($id); + } + + #[ReturnTypeWillChange] + public function gc(int $max_lifetime): int + { + return $this->_handler->gc($max_lifetime); + } + + public function open(string $path, string $name): bool + { + return $this->_handler->open($path, $name); + } + + #[ReturnTypeWillChange] + public function read(string $id): string + { + return $this->_handler->read($id); + } + + public function write(string $id, string $data): bool + { + return $this->_handler->write($id, $data); + } +} \ No newline at end of file diff --git a/vendor/fatfree/template.php b/vendor/fatfree/template.php index 57062ea..431d607 100644 --- a/vendor/fatfree/template.php +++ b/vendor/fatfree/template.php @@ -275,9 +275,9 @@ class Template extends Preview { if (preg_match('/^(.{0,'.$w.'}?)<(\/?)(?:F3:)?'. '('.$this->tags.')\b((?:\s+[\w.:@!\-]+'. '(?:\h*=\h*(?:"(?:.*?)"|\'(?:.*?)\'))?|'. - '\h*\{\{.+?\}\})*)\h*(\/?)>/is', + '\h*\{\{.+?\}\})*)\s*(\/?)>/is', substr($text,$ptr),$match)) { - if (strlen($tmp) || $match[1]) + if (strlen($tmp) || isset($match[1])) $tree[]=$tmp.$match[1]; // Element node if ($match[2]) { @@ -286,10 +286,10 @@ class Template extends Preview { for($i=count($tree)-1;$i>=0;--$i) { $item=$tree[$i]; if (is_array($item) && - array_key_exists($match[3],$item) && - !isset($item[$match[3]][0])) { + array_key_exists($k=strtolower($match[3]),$item) && + !isset($item[$k][0])) { // Start tag found - $tree[$i][$match[3]]+=array_reverse($stack); + $tree[$i][$k]+=array_reverse($stack); $tree=array_slice($tree,0,$i+1); break; } @@ -298,7 +298,7 @@ class Template extends Preview { } else { // Start tag - $node=&$tree[][$match[3]]; + $node=&$tree[][strtolower($match[3])]; $node=[]; if ($match[4]) { // Process attributes diff --git a/vendor/fatfree/web.php b/vendor/fatfree/web.php index 4019ff4..dd0242b 100644 --- a/vendor/fatfree/web.php +++ b/vendor/fatfree/web.php @@ -359,7 +359,8 @@ class Web extends Prefab { curl_setopt($curl,CURLOPT_POSTFIELDS,$options['content']); if (isset($options['proxy'])) curl_setopt($curl,CURLOPT_PROXY,$options['proxy']); - curl_setopt($curl,CURLOPT_ENCODING,'gzip,deflate'); + curl_setopt($curl,CURLOPT_ENCODING,isset($options['encoding']) + ? $options['encoding'] : 'gzip,deflate'); $timeout=isset($options['timeout'])? $options['timeout']: ini_get('default_socket_timeout'); @@ -591,7 +592,7 @@ class Web extends Prefab { * @param $url string * @param $options array **/ - function request($url,array $options=NULL) { + function request($url,?array $options=NULL) { $fw=Base::instance(); $parts=parse_url($url); if (empty($parts['scheme'])) { @@ -617,7 +618,8 @@ class Web extends Prefab { } $this->subst($options['header'], [ - 'Accept-Encoding: gzip,deflate', + 'Accept-Encoding: '.(isset($options['encoding'])? + $options['encoding']:'gzip,deflate'), 'User-Agent: '.(isset($options['user_agent'])? $options['user_agent']: 'Mozilla/5.0 (compatible; '.php_uname('s').')'), diff --git a/vendor/fatfree/web/oauth2.php b/vendor/fatfree/web/oauth2.php index eda6e45..912086c 100644 --- a/vendor/fatfree/web/oauth2.php +++ b/vendor/fatfree/web/oauth2.php @@ -39,7 +39,7 @@ class OAuth2 extends \Magic { **/ function uri($endpoint,$query=TRUE) { return $endpoint.($query?('?'. - http_build_query($this->args,null,'&',$this->enc_type)):''); + http_build_query($this->args,'','&',$this->enc_type)):''); } /** @@ -53,7 +53,7 @@ class OAuth2 extends \Magic { $web=\Web::instance(); $options=[ 'method'=>$method, - 'content'=>http_build_query($this->args,null,'&',$this->enc_type), + 'content'=>http_build_query($this->args,'','&',$this->enc_type), 'header'=>['Accept: application/json'] ]; if ($token) diff --git a/vendor/fatfree/web/openid.php b/vendor/fatfree/web/openid.php index 6e84b61..96b8c2b 100644 --- a/vendor/fatfree/web/openid.php +++ b/vendor/fatfree/web/openid.php @@ -141,7 +141,7 @@ class OpenID extends \Magic { * @param $attr array * @param $reqd string|array **/ - function auth($proxy=NULL,$attr=[],array $reqd=NULL) { + function auth($proxy=NULL,$attr=[],?array $reqd=NULL) { $fw=\Base::instance(); $root=$fw->SCHEME.'://'.$fw->HOST; if (empty($this->args['trust_root'])) diff --git a/vendor/fatfree/web/pingback.php b/vendor/fatfree/web/pingback.php index 28c51a5..ef05582 100644 --- a/vendor/fatfree/web/pingback.php +++ b/vendor/fatfree/web/pingback.php @@ -69,7 +69,7 @@ class Pingback extends \Prefab { $parts['host']==$fw->HOST) { $req=$web->request($source); $doc=new \DOMDocument('1.0',$fw->ENCODING); - $doc->stricterrorchecking=FALSE; + $doc->strictErrorChecking=FALSE; $doc->recover=TRUE; if (@$doc->loadhtml($req['body'])) { // Parse anchor tags