From 7bee17494e939af3b4f8a3ad73b2637322bb7e4a Mon Sep 17 00:00:00 2001 From: kouralex <1723419+kouralex@users.noreply.github.com> Date: Thu, 3 Nov 2022 15:24:30 +0200 Subject: [PATCH 1/2] add support for PHP 8.1 --- composer.json | 7 ++++--- controller/Controller.php | 14 +++++++------- controller/RestController.php | 4 ++-- controller/WebController.php | 8 ++++---- model/Concept.php | 4 ++-- model/ConceptSearchParameters.php | 6 +++--- model/Model.php | 6 +++--- model/Request.php | 10 +++++----- model/sparql/GenericSparql.php | 4 ++-- tests/PluginRegisterTest.php | 2 +- tests/VocabularyTest.php | 4 ++-- 11 files changed, 35 insertions(+), 34 deletions(-) diff --git a/composer.json b/composer.json index 756703de3..76b958cba 100644 --- a/composer.json +++ b/composer.json @@ -34,9 +34,10 @@ "components/jquery": "3.6.*", "components/handlebars.js": "v4.7.7", "davidstutz/bootstrap-multiselect": "v1.1.1", - "easyrdf/easyrdf": "1.1.*", + "sweetrdf/easyrdf": "1.7.*", "etdsolutions/waypoints": "4.0.0", "symfony/polyfill-php80": "1.*", + "symfony/polyfill-php81": "1.*", "twig/twig": "^2.15.3", "twig/extensions": "1.5.*", "twbs/bootstrap": "5.1.*", @@ -49,7 +50,7 @@ "ext-intl": "*", "ext-mbstring": "*", "ext-xsl": "*", - "monolog/monolog": "1.23.*", + "monolog/monolog": "1.27.*", "newerton/jquery-mousewheel": "dev-master", "pamelafox/lscache": "1.0.5" }, @@ -57,7 +58,7 @@ "phpunit/phpunit": "9.5.*", "umpirsky/twig-gettext-extractor": "1.3.*", "symfony/dom-crawler": "5.4.*", - "mockery/mockery": "1.3.5" + "mockery/mockery": "1.5.1" }, "autoload": { "classmap": ["controller/", "model/", "model/sparql/"] diff --git a/controller/Controller.php b/controller/Controller.php index bb0e09485..0d3ade953 100644 --- a/controller/Controller.php +++ b/controller/Controller.php @@ -90,17 +90,17 @@ protected function negotiateFormat($choices, $accept, $format) private function isSecure() { - if ($protocol = filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_PROTO', FILTER_SANITIZE_STRING)) { + if ($protocol = filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_PROTO', FILTER_SANITIZE_FULL_SPECIAL_CHARS)) { return \in_array(strtolower($protocol), ['https', 'on', 'ssl', '1'], true); } - return filter_input(INPUT_SERVER, 'HTTPS', FILTER_SANITIZE_STRING) !== null; + return filter_input(INPUT_SERVER, 'HTTPS', FILTER_SANITIZE_FULL_SPECIAL_CHARS) !== null; } private function guessBaseHref() { - $script_name = filter_input(INPUT_SERVER, 'SCRIPT_NAME', FILTER_SANITIZE_STRING); - $script_filename = filter_input(INPUT_SERVER, 'SCRIPT_FILENAME', FILTER_SANITIZE_STRING); + $script_name = filter_input(INPUT_SERVER, 'SCRIPT_NAME', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $script_filename = filter_input(INPUT_SERVER, 'SCRIPT_FILENAME', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $script_filename = realpath($script_filename); // resolve any symlinks (see #274) $script_filename = str_replace("\\", "/", $script_filename); // fixing windows paths with \ (see #309) $base_dir = __DIR__; // Absolute path to your installation, ex: /var/www/mywebsite @@ -109,9 +109,9 @@ private function guessBaseHref() $base_url = preg_replace("!^{$doc_root}!", '', $base_dir); $base_url = str_replace('/controller', '/', $base_url); $protocol = $this->isSecure() ? 'https' : 'http'; - $port = filter_input(INPUT_SERVER, 'SERVER_PORT', FILTER_SANITIZE_STRING); + $port = filter_input(INPUT_SERVER, 'SERVER_PORT', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $disp_port = ($port == 80 || $port == 443) ? '' : ":$port"; - $domain = filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_STRING); + $domain = filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_FULL_SPECIAL_CHARS); return "$protocol://{$domain}{$disp_port}{$base_url}"; } @@ -308,7 +308,7 @@ protected function sendNotModifiedHeader($modifiedDate): bool protected function getIfModifiedSince() { $ifModifiedSince = null; - $ifModSinceHeader = filter_input(INPUT_SERVER, 'HTTP_IF_MODIFIED_SINCE', FILTER_SANITIZE_STRING); + $ifModSinceHeader = filter_input(INPUT_SERVER, 'HTTP_IF_MODIFIED_SINCE', FILTER_SANITIZE_FULL_SPECIAL_CHARS); if ($ifModSinceHeader) { // example value set by a browser: "Mon, 11 May 2020 10:46:57 GMT" $ifModifiedSince = new DateTime($ifModSinceHeader); diff --git a/controller/RestController.php b/controller/RestController.php index 562a3d2d6..ba6f9c89f 100644 --- a/controller/RestController.php +++ b/controller/RestController.php @@ -23,7 +23,7 @@ class RestController extends Controller private function returnJson($data) { // wrap with JSONP callback if requested - if (filter_input(INPUT_GET, 'callback', FILTER_SANITIZE_STRING)) { + if (filter_input(INPUT_GET, 'callback', FILTER_SANITIZE_FULL_SPECIAL_CHARS)) { header("Content-type: application/javascript; charset=utf-8"); echo filter_input(INPUT_GET, 'callback', FILTER_UNSAFE_RAW) . "(" . json_encode($data) . ");"; return; @@ -32,7 +32,7 @@ private function returnJson($data) // otherwise negotiate suitable format for the response and return that $negotiator = new \Negotiation\Negotiator(); $priorities = array('application/json', 'application/ld+json'); - $best = filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_STRING) ? $negotiator->getBest(filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_STRING), $priorities) : null; + $best = filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ? $negotiator->getBest(filter_input(INPUT_SERVER, 'HTTP_ACCEPT', FILTER_SANITIZE_FULL_SPECIAL_CHARS), $priorities) : null; $format = ($best !== null) ? $best->getValue() : $priorities[0]; header("Content-type: $format; charset=utf-8"); header("Vary: Accept"); // inform caches that we made a choice based on Accept header diff --git a/controller/WebController.php b/controller/WebController.php index 734514afe..5afe6dd3d 100644 --- a/controller/WebController.php +++ b/controller/WebController.php @@ -82,8 +82,8 @@ public function __construct($model) public function guessLanguage($vocid = null) { // 1. select language based on SKOSMOS_LANGUAGE cookie - if (filter_input(INPUT_COOKIE, 'SKOSMOS_LANGUAGE', FILTER_SANITIZE_STRING)) { - return filter_input(INPUT_COOKIE, 'SKOSMOS_LANGUAGE', FILTER_SANITIZE_STRING); + if (filter_input(INPUT_COOKIE, 'SKOSMOS_LANGUAGE', FILTER_SANITIZE_FULL_SPECIAL_CHARS)) { + return filter_input(INPUT_COOKIE, 'SKOSMOS_LANGUAGE', FILTER_SANITIZE_FULL_SPECIAL_CHARS); } // 2. if vocabulary given, select based on the default language of the vocabulary @@ -101,7 +101,7 @@ public function guessLanguage($vocid = null) $this->negotiator = new \Negotiation\LanguageNegotiator(); $langcodes = array_keys($this->languages); // using a random language from the configured UI languages when there is no accept language header set - $acceptLanguage = filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE', FILTER_SANITIZE_STRING) ? filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE', FILTER_SANITIZE_STRING) : $langcodes[0]; + $acceptLanguage = filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ? filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE', FILTER_SANITIZE_FULL_SPECIAL_CHARS) : $langcodes[0]; $bestLang = $this->negotiator->getBest($acceptLanguage, $langcodes); if (isset($bestLang) && in_array($bestLang, $langcodes)) { return $bestLang->getValue(); @@ -566,7 +566,7 @@ public function invokeGenericErrorPage($request, $message = null) 'request' => $request, 'vocab' => $request->getVocab(), 'message' => $message, - 'requested_page' => filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING), + 'requested_page' => filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_FULL_SPECIAL_CHARS), )); } diff --git a/model/Concept.php b/model/Concept.php index 8625b1a2e..0c6ae3a74 100644 --- a/model/Concept.php +++ b/model/Concept.php @@ -869,8 +869,8 @@ private function getForeignLabelList($prop, $key) { foreach ($labels as $lit) { // filtering away subsets of the current language eg. en vs en-GB - if ($lit->getLang() != $this->clang && strpos($lit->getLang(), $this->getEnvLang() . '-') !== 0) { - $langCode = $lit->getLang() ? $lit->getLang() : ''; + $langCode = strval($lit->getLang()); + if ($langCode != $this->clang && strpos($langCode, $this->getEnvLang() . '-') !== 0) { $ret[$langCode][$key][] = new ConceptPropertyValueLiteral($this->model, $this->vocab, $this->resource, $lit, $prop); } } diff --git a/model/ConceptSearchParameters.php b/model/ConceptSearchParameters.php index 890bd09de..828f39ecb 100644 --- a/model/ConceptSearchParameters.php +++ b/model/ConceptSearchParameters.php @@ -70,7 +70,7 @@ public function getSearchTerm() : string $term = $this->request->getQueryParamRaw('q') !== null ? $this->request->getQueryParamRaw('q') : $this->request->getQueryParamRaw('query'); if ((!isset($term) || strlen(trim($term)) === 0) && $this->rest) $term = $this->request->getQueryParamRaw('label'); - $term = trim($term); // surrounding whitespace is not considered significant + $term = trim(strval($term)); // surrounding whitespace is not considered significant $term = Normalizer::normalize( $term, Normalizer::FORM_C ); //Normalize decomposed unicode characters #1184 if ($this->rest) { return $term; @@ -96,8 +96,8 @@ private function getDefaultTypeLimit() $type = array('skos:Concept'); if ($this->request->getVocab()) { $conf = $this->request->getVocab()->getConfig(); - $type[] = $conf->getArrayClassURI(); - $type[] = $conf->getGroupClassURI(); + $type[] = strval($conf->getArrayClassURI()); + $type[] = strval($conf->getGroupClassURI()); } return array_filter($type, 'strlen'); } diff --git a/model/Model.php b/model/Model.php index 4c313255a..72d731e0e 100644 --- a/model/Model.php +++ b/model/Model.php @@ -276,7 +276,7 @@ public function searchConceptsAndInfo($params) $params->setUnique(true); $allhits = $this->searchConcepts($params); $count = sizeof($allhits); - $hits = array_slice($allhits, $params->getOffset(), $params->getSearchLimit()); + $hits = array_slice($allhits, intval($params->getOffset()), $params->getSearchLimit()); $ret = array(); $uris = array(); @@ -521,8 +521,8 @@ public function guessVocabularyFromURI($uri, $preferredVocabId = null) // try to guess the URI space and look it up in the cache $res = new EasyRdf\Resource($uri); - $namespace = substr($uri, 0, -strlen($res->localName())); - if (array_key_exists($namespace, $this->vocabsByUriSpace)) { + $namespace = substr(strval($uri), 0, -strlen(strval($res->localName()))); + if ($namespace && array_key_exists($namespace, $this->vocabsByUriSpace)) { $vocabs = $this->vocabsByUriSpace[$namespace]; return $this->disambiguateVocabulary($vocabs, $uri, $preferredVocabId); } diff --git a/model/Request.php b/model/Request.php index e05439699..a1bf02c85 100644 --- a/model/Request.php +++ b/model/Request.php @@ -75,7 +75,7 @@ public function setServerConstant($paramName, $value) public function getQueryParam($paramName) { if (!isset($this->queryParams[$paramName])) return null; - $val = filter_var($this->queryParams[$paramName], FILTER_SANITIZE_STRING); + $val = filter_var($this->queryParams[$paramName], FILTER_SANITIZE_FULL_SPECIAL_CHARS); return ($val !== null ? str_replace('\\', '', $val) : null); } @@ -92,7 +92,7 @@ public function getQueryParamRaw($paramName) public function getQueryParamPOST($paramName) { if (!isset($this->queryParamsPOST[$paramName])) return null; - return filter_var($this->queryParamsPOST[$paramName], FILTER_SANITIZE_STRING); + return filter_var($this->queryParamsPOST[$paramName], FILTER_SANITIZE_FULL_SPECIAL_CHARS); } public function getQueryParamBoolean($paramName, $default) @@ -107,7 +107,7 @@ public function getQueryParamBoolean($paramName, $default) public function getServerConstant($paramName) { if (!isset($this->serverConstants[$paramName])) return null; - return filter_var($this->serverConstants[$paramName], FILTER_SANITIZE_STRING); + return filter_var($this->serverConstants[$paramName], FILTER_SANITIZE_FULL_SPECIAL_CHARS); } public function getLang() @@ -180,7 +180,7 @@ public function getRequestUri() public function getLangUrl($newlang=null) { $script_name = str_replace('/index.php', '', $this->getServerConstant('SCRIPT_NAME')); - $langurl = substr(str_replace($script_name, '', $this->getServerConstant('REQUEST_URI')), 1); + $langurl = substr(str_replace($script_name, '', strval($this->getServerConstant('REQUEST_URI'))), 1); if ($newlang !== null) { $langurl = preg_replace("#^(.*/)?{$this->lang}/#", "$1{$newlang}/", $langurl); } @@ -218,7 +218,7 @@ public function getURI() public function setURI($uri) { if ($uri !== '') { - $this->uri = rtrim($uri); + $this->uri = rtrim(strval($uri)); } } diff --git a/model/sparql/GenericSparql.php b/model/sparql/GenericSparql.php index 5a247f9df..2d82bb404 100644 --- a/model/sparql/GenericSparql.php +++ b/model/sparql/GenericSparql.php @@ -129,8 +129,8 @@ protected function initializeHttpClient() { // client, set the same type of cache control headers also in subsequent // in the SPARQL requests (this is useful for performance testing) // @codeCoverageIgnoreStart - $cacheControl = filter_input(INPUT_SERVER, 'HTTP_CACHE_CONTROL', FILTER_SANITIZE_STRING); - $pragma = filter_input(INPUT_SERVER, 'HTTP_PRAGMA', FILTER_SANITIZE_STRING); + $cacheControl = filter_input(INPUT_SERVER, 'HTTP_CACHE_CONTROL', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + $pragma = filter_input(INPUT_SERVER, 'HTTP_PRAGMA', FILTER_SANITIZE_FULL_SPECIAL_CHARS); if ($cacheControl !== null || $pragma !== null) { $val = $pragma !== null ? $pragma : $cacheControl; $httpclient->setHeaders('Cache-Control', $val); diff --git a/tests/PluginRegisterTest.php b/tests/PluginRegisterTest.php index 8d4e1b5ee..624cfa189 100644 --- a/tests/PluginRegisterTest.php +++ b/tests/PluginRegisterTest.php @@ -16,7 +16,7 @@ protected function setUp() : void 'global-plugin-charlie', 'test-plugin3' ))) - ->setMethods(['getPlugins']) + ->onlyMethods(['getPlugins']) ->getMock(); $this->stubplugs = array ('imaginary-plugin' => array ( 'js' => array ( 0 => 'imaginaryPlugin.js', ), 'css' => array ( 0 => 'stylesheet.css', ), diff --git a/tests/VocabularyTest.php b/tests/VocabularyTest.php index 425d45aa8..e6ac028cb 100644 --- a/tests/VocabularyTest.php +++ b/tests/VocabularyTest.php @@ -389,7 +389,7 @@ public function testSearchConceptsAlphabeticalEverything() { public function testGetBreadCrumbs() { $model = new Model(new GlobalConfig('/../tests/testconfig.ttl')); $resource = $this->getMockBuilder('EasyRdf\Resource')->disableOriginalConstructor()->getMock(); - $vocabstub = $this->getMockBuilder('Vocabulary')->setMethods(array('getConceptTransitiveBroaders'))->setConstructorArgs(array($model, $resource))->getMock(); + $vocabstub = $this->getMockBuilder('Vocabulary')->onlyMethods(array('getConceptTransitiveBroaders'))->setConstructorArgs(array($model, $resource))->getMock(); $vocabstub->method('getConceptTransitiveBroaders')->willReturn(array ( 'http://www.yso.fi/onto/yso/p4762' => array ( 'label' => 'objects', ), 'http://www.yso.fi/onto/yso/p1674' => array ( 'label' => 'physical whole', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p4762', ), ), 'http://www.yso.fi/onto/yso/p14606' => array ( 'label' => 'layers', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p1674', ), ), )); $result = $vocabstub->getBreadCrumbs('en', 'http://www.yso.fi/onto/yso/p14606'); foreach($result['breadcrumbs'][0] as $crumb) @@ -404,7 +404,7 @@ public function testGetBreadCrumbs() { public function testGetBreadCrumbsShortening() { $model = new Model(new GlobalConfig('/../tests/testconfig.ttl')); $resource = $this->getMockBuilder('EasyRdf\Resource')->disableOriginalConstructor()->getMock(); - $vocabstub = $this->getMockBuilder('Vocabulary')->setMethods(array('getConceptTransitiveBroaders'))->setConstructorArgs(array($model, $resource))->getMock(); + $vocabstub = $this->getMockBuilder('Vocabulary')->onlyMethods(array('getConceptTransitiveBroaders'))->setConstructorArgs(array($model, $resource))->getMock(); $vocabstub->method('getConceptTransitiveBroaders')->willReturn(array ( 'http://www.yso.fi/onto/yso/p4762' => array ( 'label' => 'objects', ), 'http://www.yso.fi/onto/yso/p13871' => array ( 'label' => 'thai language', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p10834', ), ), 'http://www.yso.fi/onto/yso/p556' => array ( 'label' => 'languages', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p2881', ), ), 'http://www.yso.fi/onto/yso/p8965' => array ( 'label' => 'Sino-Tibetan languages', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p556', ), ), 'http://www.yso.fi/onto/yso/p3358' => array ( 'label' => 'systems', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p4762', ), ), 'http://www.yso.fi/onto/yso/p10834' => array ( 'label' => 'Tai languages', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p8965', ), ), 'http://www.yso.fi/onto/yso/p2881' => array ( 'label' => 'cultural systems', 'direct' => array ( 0 => 'http://www.yso.fi/onto/yso/p3358', ), ), ) ); $result = $vocabstub->getBreadCrumbs('en', 'http://www.yso.fi/onto/yso/p13871'); $this->assertEquals(6, sizeof($result['breadcrumbs'][0])); From cb96e562e4c223eb1feb81b7a2482e32e9f71c56 Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Thu, 9 Feb 2023 13:08:35 +0200 Subject: [PATCH 2/2] CI: set PHP 8.1 as non-experimental, add PHP 8.2 as experimental --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46129d036..d6282bd89 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,10 +12,10 @@ jobs: strategy: fail-fast: false matrix: - php_version: ["7.3", "7.4", "8.0"] + php_version: ["7.3", "7.4", "8.0", "8.1"] experimental: [false] include: - - php_version: "8.1" + - php_version: "8.2" experimental: true steps: