diff --git a/vendor/fatfree/lib/CHANGELOG.md b/vendor/fatfree/lib/CHANGELOG.md index b98111f..51d4f70 100644 --- a/vendor/fatfree/lib/CHANGELOG.md +++ b/vendor/fatfree/lib/CHANGELOG.md @@ -1,6 +1,18 @@ CHANGELOG -3.7.3 +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) +* Fix: check for critical schemes in url validation +* Fix: plural format syntax with empty param, [#325](https://github.com/bcosca/fatfree-core/issues/325) +* Fix: DB mapper not able to fetch field scheme in sqlite views +* Fix: capitalization of array key X-Http-Method-Override in headers [#327](https://github.com/bcosca/fatfree-core/issues/327) +* Fix SMTP: allow RFC2047 encoded words in From/To/Cc/Bcc headers +* Fix: use correct ternary value, [#323](https://github.com/bcosca/fatfree-core/issues/323) +* 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) diff --git a/vendor/fatfree/lib/COPYING b/vendor/fatfree/lib/COPYING old mode 100755 new mode 100644 diff --git a/vendor/fatfree/lib/README.md b/vendor/fatfree/lib/README.md new file mode 100644 index 0000000..c55722c --- /dev/null +++ b/vendor/fatfree/lib/README.md @@ -0,0 +1,29 @@ +# fatfree-core +Fat-Free Framework core library + +### Usage: + +First make sure to add a proper url rewrite configuration to your server, see https://fatfreeframework.com/3.6/routing-engine#DynamicWebSites + +**without composer:** + +```php +$f3 = require('lib/base.php'); +``` + +**with composer:** + +``` +composer require bcosca/fatfree-core +``` + +```php +require("vendor/autoload.php"); +$f3 = \Base::instance(); +``` + +--- +For the main repository (demo package), see https://github.com/bcosca/fatfree +For the test bench and unit tests, see https://github.com/f3-factory/fatfree-dev +For the user guide, see https://fatfreeframework.com/user-guide +For the documentation, see https://fatfreeframework.com/api-reference diff --git a/vendor/fatfree/lib/audit.php b/vendor/fatfree/lib/audit.php index a0d4338..26fe349 100644 --- a/vendor/fatfree/lib/audit.php +++ b/vendor/fatfree/lib/audit.php @@ -36,7 +36,8 @@ class Audit extends Prefab { * @param $str string **/ function url($str) { - return is_string(filter_var($str,FILTER_VALIDATE_URL)); + return is_string(filter_var($str,FILTER_VALIDATE_URL)) + && !preg_match('/^(javascript|php):\/\/.*$/i', $str); } /** diff --git a/vendor/fatfree/lib/base.php b/vendor/fatfree/lib/base.php index dfb59c1..7c75c79 100644 --- a/vendor/fatfree/lib/base.php +++ b/vendor/fatfree/lib/base.php @@ -45,7 +45,7 @@ final class Base extends Prefab implements ArrayAccess { //@{ Framework details const PACKAGE='Fat-Free Framework', - VERSION='3.7.3-Release'; + VERSION='3.8.1-Dev'; //@} //@{ HTTP status codes (RFC 2616) @@ -159,7 +159,7 @@ final class Base extends Prefab implements ArrayAccess { **/ private function cut($key) { return preg_split('/\[\h*[\'"]?(.+?)[\'"]?\h*\]|(->)|\./', - $key,NULL,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE); + $key,-1,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE); } /** @@ -221,11 +221,11 @@ final class Base extends Prefab implements ArrayAccess { * @return mixed */ function cast($val) { - if (preg_match('/^(?:0x[0-9a-f]+|0[0-7]+|0b[01]+)$/i',$val)) + if ($val && preg_match('/^(?:0x[0-9a-f]+|0[0-7]+|0b[01]+)$/i',$val)) return intval($val,0); if (is_numeric($val)) return $val+0; - $val=trim($val); + $val=trim($val?:''); if (preg_match('/^\w+$/i',$val) && defined($val)) return constant($val); return $val; @@ -389,18 +389,18 @@ final class Base extends Prefab implements ArrayAccess { if (version_compare(PHP_VERSION, '7.3.0') >= 0) { unset($jar['expire']); if (isset($_COOKIE[$parts[1]])) - setcookie($parts[1],NULL,['expires'=>0]+$jar); + setcookie($parts[1],'',['expires'=>0]+$jar); if ($ttl) $jar['expires']=$time+$ttl; - setcookie($parts[1],$val,$jar); + setcookie($parts[1],$val?:'',$jar); } else { unset($jar['samesite']); if (isset($_COOKIE[$parts[1]])) call_user_func_array('setcookie', - array_merge([$parts[1],NULL],['expire'=>0]+$jar)); + array_merge([$parts[1],''],['expire'=>0]+$jar)); if ($ttl) $jar['expire']=$time+$ttl; - call_user_func_array('setcookie',[$parts[1],$val]+$jar); + call_user_func_array('setcookie',[$parts[1],$val?:'']+$jar); } $_COOKIE[$parts[1]]=$val; return $val; @@ -501,11 +501,11 @@ final class Base extends Prefab implements ArrayAccess { if (version_compare(PHP_VERSION, '7.3.0') >= 0) { $jar['expires']=$jar['expire']; unset($jar['expire']); - setcookie($parts[1],NULL,$jar); + setcookie($parts[1],'',$jar); } else { unset($jar['samesite']); call_user_func_array('setcookie', - array_merge([$parts[1],NULL],$jar)); + array_merge([$parts[1],''],$jar)); } unset($_COOKIE[$parts[1]]); } @@ -713,7 +713,7 @@ final class Base extends Prefab implements ArrayAccess { **/ function split($str,$noempty=TRUE) { return array_map('trim', - preg_split('/[,;|]/',$str,0,$noempty?PREG_SPLIT_NO_EMPTY:0)); + preg_split('/[,;|]/',$str?:'',0,$noempty?PREG_SPLIT_NO_EMPTY:0)); } /** @@ -829,7 +829,7 @@ final class Base extends Prefab implements ArrayAccess { **/ function hash($str) { return str_pad(base_convert( - substr(sha1($str),-16),16,36),11,'0',STR_PAD_LEFT); + substr(sha1($str?:''),-16),16,36),11,'0',STR_PAD_LEFT); } /** @@ -968,10 +968,11 @@ final class Base extends Prefab implements ArrayAccess { isset($prop)?$prop:null ] ); + $php81=version_compare(PHP_VERSION, '8.1.0')>=0; switch ($type) { case 'plural': preg_match_all('/(?\w+)'. - '(?:\s*\{\s*(?.+?)\s*\})/', + '(?:\s*\{\s*(?.*?)\s*\})/', $mod,$matches,PREG_SET_ORDER); $ord=['zero','one','two']; foreach ($matches as $match) { @@ -1051,19 +1052,42 @@ final class Base extends Prefab implements ArrayAccess { ($frac?strlen($frac)-2:0), $decimal_point,$thousands_sep); case 'date': - if (empty($mod) || $mod=='short') - $prop='%x'; - elseif ($mod=='full') - $prop='%A, %d %B %Y'; - elseif ($mod!='custom') - $prop='%d %B %Y'; - return strftime($prop,$args[$pos]); + 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); + return $formatter->format($args[$pos]); + } else { + if (empty($mod) || $mod=='short') + $prop='%x'; + elseif ($mod=='full') + $prop='%A, %d %B %Y'; + elseif ($mod!='custom') + $prop='%d %B %Y'; + return strftime($prop,$args[$pos]); + } case 'time': - if (empty($mod) || $mod=='short') - $prop='%X'; - elseif ($mod!='custom') - $prop='%r'; - return strftime($prop,$args[$pos]); + if ($php81) { + $lang = $this->split($this->LANGUAGE); + // requires intl extension + $formatter = new IntlDateFormatter($lang[0], + IntlDateFormatter::NONE, + (empty($mod) || $mod=='short') + ? IntlDateFormatter::SHORT : + ($mod=='full' ? IntlDateFormatter::LONG : IntlDateFormatter::MEDIUM), + IntlTimeZone::createTimeZone($this->hive['TZ'])); + return $formatter->format($args[$pos]); + } else { + if (empty($mod) || $mod=='short') + $prop='%X'; + elseif ($mod!='custom') + $prop='%r'; + return strftime($prop,$args[$pos]); + } default: return $expr[0]; } @@ -1089,7 +1113,7 @@ final class Base extends Prefab implements ArrayAccess { * @param $code string **/ function language($code) { - $code=preg_replace('/\h+|;q=[0-9.]+/','',$code); + $code=preg_replace('/\h+|;q=[0-9.]+/','',$code?:''); $code.=($code?',':'').$this->fallback; $this->languages=[]; foreach (array_reverse(explode(',',$code)) as $lang) @@ -1225,7 +1249,7 @@ final class Base extends Prefab implements ArrayAccess { $time=microtime(TRUE); header_remove('Pragma'); header('Cache-Control: max-age='.$secs); - header('Expires: '.gmdate('r',$time+$secs)); + header('Expires: '.gmdate('r',round($time+$secs))); header('Last-Modified: '.gmdate('r')); } else { @@ -1342,7 +1366,7 @@ final class Base extends Prefab implements ArrayAccess { $loggable=$this->split($loggable); foreach ($loggable as $status) if ($status=='*' || - preg_match('/^'.preg_replace('/\D/','\d',$status).'$/',$code)) { + preg_match('/^'.preg_replace('/\D/','\d',$status).'$/',(string) $code)) { error_log($text); foreach (explode("\n",$trace) as $nexus) if ($nexus) @@ -1376,7 +1400,7 @@ final class Base extends Prefab implements ArrayAccess { if ($this->hive['CLI']) echo PHP_EOL.'==================================='.PHP_EOL. 'ERROR '.$error['code'].' - '.$error['status'].PHP_EOL. - $error['text'].PHP_EOL.PHP_EOL.$error['trace']; + $error['text'].PHP_EOL.PHP_EOL.(isset($error['trace']) ? $error['trace'] : ''); else echo $this->hive['AJAX']? json_encode($error): @@ -1424,7 +1448,7 @@ final class Base extends Prefab implements ArrayAccess { if (empty($parts[4])) user_error(sprintf(self::E_Pattern,$pattern),E_USER_ERROR); $url=parse_url($parts[4]); - parse_str(@$url['query'],$GLOBALS['_GET']); + parse_str(isset($url['query'])?$url['query']:'',$GLOBALS['_GET']); if (preg_match('/GET|HEAD/',$verb)) $GLOBALS['_GET']=array_merge($GLOBALS['_GET'],$args); $GLOBALS['_POST']=$verb=='POST'?$args:[]; @@ -1775,7 +1799,7 @@ final class Base extends Prefab implements ArrayAccess { ++$ctr; if ($ctr/$kbps>($elapsed=microtime(TRUE)-$now) && !connection_aborted()) - usleep(1e6*($ctr/$kbps-$elapsed)); + usleep(round(1e6*($ctr/$kbps-$elapsed))); echo $part; } } @@ -2234,6 +2258,7 @@ final class Base extends Prefab implements ArrayAccess { * @return mixed * @param $key string **/ + #[\ReturnTypeWillChange] function offsetexists($key) { return $this->exists($key); } @@ -2244,6 +2269,7 @@ final class Base extends Prefab implements ArrayAccess { * @param $key string * @param $val mixed **/ + #[\ReturnTypeWillChange] function offsetset($key,$val) { return $this->set($key,$val); } @@ -2253,6 +2279,7 @@ final class Base extends Prefab implements ArrayAccess { * @return mixed * @param $key string **/ + #[\ReturnTypeWillChange] function &offsetget($key) { $val=&$this->ref($key); return $val; @@ -2262,6 +2289,7 @@ final class Base extends Prefab implements ArrayAccess { * Convenience method for removing hive key * @param $key string **/ + #[\ReturnTypeWillChange] function offsetunset($key) { $this->clear($key); } @@ -2378,7 +2406,7 @@ final class Base extends Prefab implements ArrayAccess { $req.='?'.$query; } $_SERVER['REQUEST_URI']=$req; - parse_str($query,$GLOBALS['_GET']); + parse_str($query?:'',$GLOBALS['_GET']); } elseif (function_exists('getallheaders')) { foreach (getallheaders() as $key=>$val) { @@ -2400,8 +2428,8 @@ final class Base extends Prefab implements ArrayAccess { $headers[strtr(ucwords(strtolower(strtr( substr($key,5),'_',' '))),' ','-')]=&$_SERVER[$key]; } - if (isset($headers['X-HTTP-Method-Override'])) - $_SERVER['REQUEST_METHOD']=$headers['X-HTTP-Method-Override']; + if (isset($headers['X-Http-Method-Override'])) + $_SERVER['REQUEST_METHOD']=$headers['X-Http-Method-Override']; elseif ($_SERVER['REQUEST_METHOD']=='POST' && isset($_POST['_method'])) $_SERVER['REQUEST_METHOD']=strtoupper($_POST['_method']); $scheme=isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on' || @@ -2533,9 +2561,11 @@ final class Base extends Prefab implements ArrayAccess { if (PHP_SAPI=='cli-server' && preg_match('/^'.preg_quote($base,'/').'$/',$this->hive['URI'])) $this->reroute('/'); - if (ini_get('auto_globals_jit')) + if (ini_get('auto_globals_jit')) { // Override setting - $GLOBALS+=['_ENV'=>$_ENV,'_REQUEST'=>$_REQUEST]; + $GLOBALS['_ENV']=$_ENV; + $GLOBALS['_REQUEST']=$_REQUEST; + } // Sync PHP globals with corresponding hive keys $this->init=$this->hive; foreach (explode('|',self::GLOBALS) as $global) { @@ -2699,7 +2729,7 @@ class Cache extends Prefab { if (!$this->dsn) return TRUE; $regex='/'.preg_quote($this->prefix.'.','/').'.*'. - preg_quote($suffix,'/').'/'; + preg_quote($suffix?:'','/').'/'; $parts=explode('=',$this->dsn,2); switch ($parts[0]) { case 'apc': diff --git a/vendor/fatfree/lib/basket.php b/vendor/fatfree/lib/basket.php index 70cacee..924b84e 100644 --- a/vendor/fatfree/lib/basket.php +++ b/vendor/fatfree/lib/basket.php @@ -148,7 +148,7 @@ class Basket extends Magic { **/ function save() { if (!$this->id) - $this->id=uniqid(NULL,TRUE); + $this->id=uniqid('',TRUE); $_SESSION[$this->key][$this->id]=$this->item; return $this->item; } diff --git a/vendor/fatfree/lib/code.css b/vendor/fatfree/lib/code.css old mode 100755 new mode 100644 diff --git a/vendor/fatfree/lib/composer.json b/vendor/fatfree/lib/composer.json new file mode 100644 index 0000000..01bdca1 --- /dev/null +++ b/vendor/fatfree/lib/composer.json @@ -0,0 +1,12 @@ +{ + "name": "bcosca/fatfree-core", + "description": "A powerful yet easy-to-use PHP micro-framework designed to help you build dynamic and robust Web applications - fast!", + "homepage": "http://fatfreeframework.com/", + "license": "GPL-3.0", + "require": { + "php": ">=5.4" + }, + "autoload": { + "classmap": ["."] + } +} diff --git a/vendor/fatfree/lib/db/cursor.php b/vendor/fatfree/lib/db/cursor.php index 2fd324a..266a143 100644 --- a/vendor/fatfree/lib/db/cursor.php +++ b/vendor/fatfree/lib/db/cursor.php @@ -107,6 +107,7 @@ abstract class Cursor extends \Magic implements \IteratorAggregate { * Causes a fatal error in PHP 5.3.5 if uncommented * return ArrayIterator **/ + #[\ReturnTypeWillChange] abstract function getiterator(); diff --git a/vendor/fatfree/lib/db/jig/mapper.php b/vendor/fatfree/lib/db/jig/mapper.php index 5d26427..8f4af54 100644 --- a/vendor/fatfree/lib/db/jig/mapper.php +++ b/vendor/fatfree/lib/db/jig/mapper.php @@ -325,7 +325,7 @@ class Mapper extends \DB\Cursor { if (!array_key_exists($col,$val2)) $val2[$col]=NULL; list($v1,$v2)=[$val1[$col],$val2[$col]]; - if ($out=strnatcmp($v1,$v2)* + if ($out=strnatcmp($v1?:'',$v2?:'')* (($order==SORT_ASC)*2-1)) return $out; } @@ -383,7 +383,7 @@ class Mapper extends \DB\Cursor { return $this->update(); $db=$this->db; $now=microtime(TRUE); - while (($id=uniqid(NULL,TRUE)) && + while (($id=uniqid('',TRUE)) && ($data=&$db->read($this->file)) && isset($data[$id]) && !connection_aborted()) usleep(mt_rand(0,100)); diff --git a/vendor/fatfree/lib/db/mongo/mapper.php b/vendor/fatfree/lib/db/mongo/mapper.php index 0246f6d..71de62c 100644 --- a/vendor/fatfree/lib/db/mongo/mapper.php +++ b/vendor/fatfree/lib/db/mongo/mapper.php @@ -150,7 +150,7 @@ class Mapper extends \DB\Cursor { ); $tmp=$this->db->selectcollection( $fw->HOST.'.'.$fw->BASE.'.'. - uniqid(NULL,TRUE).'.tmp' + uniqid('',TRUE).'.tmp' ); $tmp->batchinsert($grp['retval'],['w'=>1]); $filter=[]; diff --git a/vendor/fatfree/lib/db/sql.php b/vendor/fatfree/lib/db/sql.php index 566b94a..4c5cc44 100644 --- a/vendor/fatfree/lib/db/sql.php +++ b/vendor/fatfree/lib/db/sql.php @@ -339,7 +339,7 @@ class SQL { $cmd=[ 'sqlite2?'=>[ 'SELECT * FROM pragma_table_info('.$this->quote($table).') JOIN ('. - 'SELECT sql FROM sqlite_master WHERE type=\'table\' AND '. + 'SELECT sql FROM sqlite_master WHERE (type=\'table\' OR type=\'view\') AND '. 'name='.$this->quote($table).')', 'name','type','dflt_value','notnull',0,'pk',TRUE,'sql', '/\W(%s)\W+[^,]+?AUTOINCREMENT\W/i'], diff --git a/vendor/fatfree/lib/db/sql/mapper.php b/vendor/fatfree/lib/db/sql/mapper.php index 574cc9f..52c8096 100644 --- a/vendor/fatfree/lib/db/sql/mapper.php +++ b/vendor/fatfree/lib/db/sql/mapper.php @@ -427,6 +427,7 @@ class Mapper extends \DB\Cursor { $values=''; $filter=''; $pkeys=[]; + $aikeys=[]; $nkeys=[]; $ckeys=[]; $inc=NULL; @@ -449,6 +450,9 @@ class Mapper extends \DB\Cursor { unset($field); } foreach ($this->fields as $key=>&$field) { + if ($field['auto_inc']) { + $aikeys[] = $key; + } if ($field['pkey']) { $field['previous']=$field['value']; if (!$inc && empty($field['value']) && @@ -469,7 +473,7 @@ class Mapper extends \DB\Cursor { } unset($field); } - if ($fields) { + if ($fields) { $add=$aik=''; if ($this->engine=='pgsql' && !empty($pkeys)) { $names=array_keys($pkeys); @@ -478,7 +482,7 @@ class Mapper extends \DB\Cursor { } $lID=$this->db->exec( (preg_match('/mssql|dblib|sqlsrv/',$this->engine) && - array_intersect(array_keys($pkeys),$ckeys)? + array_intersect(array_keys($aikeys),$ckeys)? 'SET IDENTITY_INSERT '.$this->table.' ON;':''). 'INSERT INTO '.$this->table.' ('.$fields.') '. 'VALUES ('.$values.')'.$add,$args diff --git a/vendor/fatfree/lib/image.php b/vendor/fatfree/lib/image.php index b7f149c..367ca6e 100644 --- a/vendor/fatfree/lib/image.php +++ b/vendor/fatfree/lib/image.php @@ -258,12 +258,12 @@ class Image { if ($width/$ratio<=$height) { $cropw=round($origh*$width/$height); imagecopyresampled($tmp,$this->data, - 0,0,($origw-$cropw)/2,0,$width,$height,$cropw,$origh); + 0,0,round(($origw-$cropw)/2),0,$width,$height,$cropw,$origh); } else { $croph=round($origw*$height/$width); imagecopyresampled($tmp,$this->data, - 0,0,0,($origh-$croph)/2,$width,$height,$origw,$croph); + 0,0,0,round(($origh-$croph)/2),$width,$height,$origw,$croph); } } else @@ -309,13 +309,13 @@ class Image { if ($align & self::POS_Left) $posx=0; if ($align & self::POS_Center) - $posx=($imgw-$ovrw)/2; + $posx=round(($imgw-$ovrw)/2); if ($align & self::POS_Right) $posx=$imgw-$ovrw; if ($align & self::POS_Top) $posy=0; if ($align & self::POS_Middle) - $posy=($imgh-$ovrh)/2; + $posy=round(($imgh-$ovrh)/2); if ($align & self::POS_Bottom) $posy=$imgh-$ovrh; if (empty($posx)) @@ -374,10 +374,14 @@ class Image { $block=$sprites[hexdec($hash[($j*$blocks+$i)*2])%$ctr]; for ($k=0,$pts=count($block);$k<$pts;++$k) $block[$k]*=$dim; - imagefilledpolygon($sprite,$block,$pts/2,$fg); + if (version_compare(PHP_VERSION, '8.1.0') >= 0) { + imagefilledpolygon($sprite,$block,$fg); + } else { + imagefilledpolygon($sprite,$block,$pts/2,$fg); + } for ($k=0;$k<4;++$k) { imagecopyresampled($this->data,$sprite, - $i*$dim/2,$j*$dim/2,0,0,$dim/2,$dim/2,$dim,$dim); + round($i*$dim/2),round($j*$dim/2),0,0,round($dim/2),round($dim/2),$dim,$dim); $this->data=imagerotate($this->data,90, imagecolorallocatealpha($this->data,0,0,0,127)); } @@ -424,25 +428,25 @@ class Image { $char=imagecreatetruecolor($block,$block); imagefill($char,0,0,$bg); imagettftext($char,$size*2,0, - ($block-$w)/2,$block-($block-$h)/2, + round(($block-$w)/2),round($block-($block-$h)/2), $fg,$path,$seed[$i]); $char=imagerotate($char,mt_rand(-30,30), imagecolorallocatealpha($char,0,0,0,127)); // Reduce to normal size $tmp[$i]=imagecreatetruecolor( - ($w=imagesx($char))/2,($h=imagesy($char))/2); + round(($w=imagesx($char))/2),round(($h=imagesy($char))/2)); imagefill($tmp[$i],0,0,IMG_COLOR_TRANSPARENT); imagecopyresampled($tmp[$i], - $char,0,0,0,0,$w/2,$h/2,$w,$h); + $char,0,0,0,0,round($w/2),round($h/2),$w,$h); imagedestroy($char); $width+=$i+1<$len?$block/2:$w/2; $height=max($height,$h/2); } - $this->data=imagecreatetruecolor($width,$height); + $this->data=imagecreatetruecolor(round($width),round($height)); imagefill($this->data,0,0,IMG_COLOR_TRANSPARENT); for ($i=0;$i<$len;++$i) { imagecopy($this->data,$tmp[$i], - $i*$block/2,($height-imagesy($tmp[$i]))/2,0,0, + round($i*$block/2),round(($height-imagesy($tmp[$i]))/2),0,0, imagesx($tmp[$i]),imagesy($tmp[$i])); imagedestroy($tmp[$i]); } diff --git a/vendor/fatfree/lib/magic.php b/vendor/fatfree/lib/magic.php index f676506..92398a5 100644 --- a/vendor/fatfree/lib/magic.php +++ b/vendor/fatfree/lib/magic.php @@ -57,6 +57,7 @@ abstract class Magic implements ArrayAccess { * @return mixed * @param $key string **/ + #[\ReturnTypeWillChange] function offsetexists($key) { return Base::instance()->visible($this,$key)? isset($this->$key): @@ -69,6 +70,7 @@ abstract class Magic implements ArrayAccess { * @param $key string * @param $val mixed **/ + #[\ReturnTypeWillChange] function offsetset($key,$val) { return Base::instance()->visible($this,$key)? ($this->$key=$val):$this->set($key,$val); @@ -79,6 +81,7 @@ abstract class Magic implements ArrayAccess { * @return mixed * @param $key string **/ + #[\ReturnTypeWillChange] function &offsetget($key) { if (Base::instance()->visible($this,$key)) $val=&$this->$key; @@ -92,6 +95,7 @@ abstract class Magic implements ArrayAccess { * @return NULL * @param $key string **/ + #[\ReturnTypeWillChange] function offsetunset($key) { if (Base::instance()->visible($this,$key)) unset($this->$key); diff --git a/vendor/fatfree/lib/session.php b/vendor/fatfree/lib/session.php index 168e5b6..9e8d600 100644 --- a/vendor/fatfree/lib/session.php +++ b/vendor/fatfree/lib/session.php @@ -21,7 +21,7 @@ */ //! Cache-based session handler -class Session { +class Session extends Magic { protected //! Session ID @@ -35,7 +35,9 @@ class Session { //! Suspect callback $onsuspect, //! Cache instance - $_cache; + $_cache, + //! Session meta data + $_data=[]; /** * Open session @@ -53,6 +55,7 @@ class Session { **/ function close() { $this->sid=NULL; + $this->_data=[]; return TRUE; } @@ -65,6 +68,7 @@ class Session { $this->sid=$id; if (!$data=$this->_cache->get($id.'.@')) return ''; + $this->_data = $data; if ($data['ip']!=$this->_ip || $data['agent']!=$this->_agent) { $fw=Base::instance(); if (!isset($this->onsuspect) || @@ -193,4 +197,29 @@ class Session { $this->_ip=$fw->IP; } + /** + * check latest meta data existence + * @param string $key + * @return bool + */ + function exists($key) { + return isset($this->_data[$key]); + } + + /** + * get meta data from latest session + * @param string $key + * @return mixed + */ + function &get($key) { + return $this->_data[$key]; + } + + function set($key,$val) { + trigger_error('Unable to set data on previous session'); + } + + function clear($key) { + trigger_error('Unable to clear data on previous session'); + } } diff --git a/vendor/fatfree/lib/smtp.php b/vendor/fatfree/lib/smtp.php index 8cef939..b329d4b 100644 --- a/vendor/fatfree/lib/smtp.php +++ b/vendor/fatfree/lib/smtp.php @@ -256,7 +256,7 @@ class SMTP extends Magic { foreach ($headers as $key=>&$val) { if (in_array($key,['From','To','Cc','Bcc'])) { $email=''; - preg_match_all('/(?:".+?" )?(?:<.+?>|[^ ,]+)/', + preg_match_all('/(?:".+?" |=\?.+?\?= )?(?:<.+?>|[^ ,]+)/', $val,$matches,PREG_SET_ORDER); foreach ($matches as $raw) $email.=($email?', ':''). @@ -283,7 +283,7 @@ class SMTP extends Magic { unset($headers['Content-Type']); $enc=$headers['Content-Transfer-Encoding']; unset($headers['Content-Transfer-Encoding']); - $hash=uniqid(NULL,TRUE); + $hash=uniqid('',TRUE); // Send mail headers $out='Content-Type: multipart/mixed; boundary="'.$hash.'"'.$eol; foreach ($headers as $key=>$val) @@ -352,7 +352,7 @@ class SMTP extends Magic { 'Content-Type'=>'text/plain; '. 'charset='.Base::instance()->ENCODING ]; - $this->host=strtolower((($this->scheme=strtolower($scheme))=='ssl'? + $this->host=strtolower((($this->scheme=strtolower($scheme?:''))=='ssl'? 'ssl':'tcp').'://'.$host); $this->port=$port; $this->user=$user; diff --git a/vendor/fatfree/lib/template.php b/vendor/fatfree/lib/template.php index fb6f21d..57062ea 100644 --- a/vendor/fatfree/lib/template.php +++ b/vendor/fatfree/lib/template.php @@ -43,7 +43,7 @@ class Template extends Preview { $out=''; foreach ($node['@attrib'] as $key=>$val) $out.='$'.$key.'='. - (preg_match('/\{\{(.+?)\}\}/',$val)? + (preg_match('/\{\{(.+?)\}\}/',$val?:'')? $this->token($val): Base::instance()->stringify($val)).'; '; return ''; diff --git a/vendor/fatfree/lib/web.php b/vendor/fatfree/lib/web.php index 7a69051..4019ff4 100644 --- a/vendor/fatfree/lib/web.php +++ b/vendor/fatfree/lib/web.php @@ -232,7 +232,7 @@ class Web extends Prefab { // Throttle output ++$ctr; if ($ctr/$kbps>$elapsed=microtime(TRUE)-$start) - usleep(1e6*($ctr/$kbps-$elapsed)); + usleep(round(1e6*($ctr/$kbps-$elapsed))); } // Send 1KiB and reset timer echo fread($handle,1024); @@ -1006,7 +1006,7 @@ if (!function_exists('gzdecode')) { if (!is_dir($tmp=$fw->TEMP)) mkdir($tmp,Base::MODE,TRUE); file_put_contents($file=$tmp.'/'.$fw->SEED.'.'. - $fw->hash(uniqid(NULL,TRUE)).'.gz',$str,LOCK_EX); + $fw->hash(uniqid('',TRUE)).'.gz',$str,LOCK_EX); ob_start(); readgzfile($file); $out=ob_get_clean();