From 81acba90dc912562aacb0ff913499e5bb05bc17c Mon Sep 17 00:00:00 2001 From: "J. King" Date: Fri, 11 Jan 2019 10:38:06 -0500 Subject: [PATCH] Use strict equality when comparing strings --- arsse.php | 2 +- lib/AbstractException.php | 2 +- lib/CLI.php | 2 +- lib/Conf.php | 2 +- lib/Database.php | 2 +- lib/Db/AbstractDriver.php | 4 +-- lib/Db/MySQL/Driver.php | 8 +++--- lib/Db/MySQL/Statement.php | 6 ++-- lib/Db/PDOError.php | 2 +- lib/Feed.php | 20 ++++++------- lib/Lang.php | 18 ++++++------ lib/Misc/Date.php | 4 +-- lib/Misc/ValueInfo.php | 10 +++---- lib/REST.php | 22 +++++++-------- lib/REST/AbstractHandler.php | 2 +- lib/REST/NextCloudNews/V1_2.php | 12 ++++---- lib/REST/Target.php | 14 +++++----- lib/REST/TinyTinyRSS/API.php | 28 +++++++++---------- lib/REST/TinyTinyRSS/Icon.php | 2 +- tests/cases/CLI/TestCLI.php | 6 ++-- tests/cases/Db/BaseDriver.php | 2 +- tests/cases/Db/BaseStatement.php | 8 +++--- tests/cases/Db/MySQLPDO/TestStatement.php | 2 +- tests/cases/Db/PostgreSQL/TestCreation.php | 2 +- tests/cases/Db/PostgreSQL/TestStatement.php | 2 +- tests/cases/Db/PostgreSQLPDO/TestCreation.php | 2 +- .../cases/Db/PostgreSQLPDO/TestStatement.php | 2 +- tests/cases/Db/SQLite3PDO/TestStatement.php | 4 +-- tests/cases/REST/TinyTinyRSS/TestAPI.php | 10 +++---- tests/cases/User/TestUser.php | 4 +-- tests/lib/DatabaseInformation.php | 8 +++--- 31 files changed, 107 insertions(+), 107 deletions(-) diff --git a/arsse.php b/arsse.php index e33d618..407be03 100644 --- a/arsse.php +++ b/arsse.php @@ -14,7 +14,7 @@ ini_set("memory_limit", "-1"); ini_set("max_execution_time", "0"); -if (\PHP_SAPI=="cli") { +if (\PHP_SAPI === "cli") { // initialize the CLI; this automatically handles --help and --version $cli = new CLI; // handle other CLI requests; some do not require configuration diff --git a/lib/AbstractException.php b/lib/AbstractException.php index 01c4e1b..ebbd691 100644 --- a/lib/AbstractException.php +++ b/lib/AbstractException.php @@ -83,7 +83,7 @@ abstract class AbstractException extends \Exception { ]; public function __construct(string $msgID = "", $vars = null, \Throwable $e = null) { - if ($msgID=="") { + if ($msgID === "") { $msg = "Exception.unknown"; $code = 10000; } else { diff --git a/lib/CLI.php b/lib/CLI.php index 7f9deac..36129e0 100644 --- a/lib/CLI.php +++ b/lib/CLI.php @@ -74,7 +74,7 @@ USAGE_TEXT; return (int) !Arsse::$db->feedUpdate((int) $args[''], true); case "conf save-defaults": $file = $args['']; - $file = ($file=="-" ? null : $file) ?? "php://output"; + $file = ($file === "-" ? null : $file) ?? "php://output"; return (int) !($this->getConf())->exportFile($file, true); case "user": $this->loadConf(); diff --git a/lib/Conf.php b/lib/Conf.php index d252a87..cfdb1fb 100644 --- a/lib/Conf.php +++ b/lib/Conf.php @@ -115,7 +115,7 @@ class Conf { * @param string $import_file Optional file to read configuration data from * @see self::importFile() */ public function __construct(string $import_file = "") { - if ($import_file != "") { + if ($import_file !== "") { $this->importFile($import_file); } } diff --git a/lib/Database.php b/lib/Database.php index 4a6fc40..9fba4da 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -364,7 +364,7 @@ class Database { $parent = (int) $parent; } // if the target parent is the folder itself, this is a circular dependence - if ($id==$parent) { + if ($id == $parent) { throw new Db\ExceptionInput("circularDependence", $errData); } // make sure both that the prospective parent exists, and that the it is not one of its children (a circular dependence); diff --git a/lib/Db/AbstractDriver.php b/lib/Db/AbstractDriver.php index 682d741..fd377b2 100644 --- a/lib/Db/AbstractDriver.php +++ b/lib/Db/AbstractDriver.php @@ -131,7 +131,7 @@ abstract class AbstractDriver implements Driver { default: throw new Exception("savepointStatusUnknown", $this->transStatus[$index]); // @codeCoverageIgnore } - if ($index==$this->transDepth) { + if ($index == $this->transDepth) { // if we've released the topmost savepoint, clean up all prior savepoints which have already been explicitly committed (or rolled back), if any while ($this->transDepth > 0 && $this->transStatus[$this->transDepth] > self::TR_PEND) { array_pop($this->transStatus); @@ -185,7 +185,7 @@ abstract class AbstractDriver implements Driver { default: throw new Exception("savepointStatusUnknown", $this->transStatus[$index]); // @codeCoverageIgnore } - if ($index==$this->transDepth) { + if ($index == $this->transDepth) { while ($this->transDepth > 0 && $this->transStatus[$this->transDepth] > self::TR_PEND) { array_pop($this->transStatus); $this->transDepth--; diff --git a/lib/Db/MySQL/Driver.php b/lib/Db/MySQL/Driver.php index 984542d..41b4d53 100644 --- a/lib/Db/MySQL/Driver.php +++ b/lib/Db/MySQL/Driver.php @@ -29,11 +29,11 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { throw new Exception("extMissing", static::driverName()); // @codeCoverageIgnore } $host = Arsse::$conf->dbMySQLHost; - if ($host[0] == "/") { + if ($host[0] === "/") { // host is a Unix socket $socket = $host; $host = ""; - } elseif(substr($host, 0, 9) == "\\\\.\\pipe\\") { + } elseif(substr($host, 0, 9) === "\\\\.\\pipe\\") { // host is a Windows named piple $socket = substr($host, 10); $host = ""; @@ -183,8 +183,8 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { protected function dispatch(string $query) { $r = $this->db->query($query); - if ($this->db->sqlstate != "00000") { - if ($this->db->sqlstate == "HY000") { + if ($this->db->sqlstate !== "00000") { + if ($this->db->sqlstate === "HY000") { list($excClass, $excMsg, $excData) = $this->buildEngineException($this->db->errno, $this->db->error); } else { list($excClass, $excMsg, $excData) = $this->buildStandardException($this->db->sqlstate, $this->db->error); diff --git a/lib/Db/MySQL/Statement.php b/lib/Db/MySQL/Statement.php index 342c6f4..b1e08ba 100644 --- a/lib/Db/MySQL/Statement.php +++ b/lib/Db/MySQL/Statement.php @@ -65,8 +65,8 @@ class Statement extends \JKingWeb\Arsse\Db\AbstractStatement { $this->types = ""; $this->values = []; // check for errors - if ($this->st->sqlstate != "00000") { - if ($this->st->sqlstate == "HY000") { + if ($this->st->sqlstate !== "00000") { + if ($this->st->sqlstate === "HY000") { list($excClass, $excMsg, $excData) = $this->buildEngineException($this->st->errno, $this->st->error); } else { list($excClass, $excMsg, $excData) = $this->buildStandardException($this->st->sqlstate, $this->st->error); @@ -98,7 +98,7 @@ class Statement extends \JKingWeb\Arsse\Db\AbstractStatement { $out = ""; for ($b = 1; $b < sizeof($query); $b++) { $a = $b - 1; - $mark = (($types[$a] ?? "") == "datetime") ? "cast(? as datetime(0))" : "?"; + $mark = (($types[$a] ?? "") === "datetime") ? "cast(? as datetime(0))" : "?"; $out .= $query[$a].$mark; } $out .= array_pop($query); diff --git a/lib/Db/PDOError.php b/lib/Db/PDOError.php index 6869e4a..bd15dc2 100644 --- a/lib/Db/PDOError.php +++ b/lib/Db/PDOError.php @@ -15,7 +15,7 @@ trait PDOError { } else { $err = $this->db->errorInfo(); } - if ($err[0]=="HY000") { + if ($err[0] === "HY000") { return static::buildEngineException($err[1], $err[2]); } else { return static::buildStandardException($err[0], $err[2]); diff --git a/lib/Feed.php b/lib/Feed.php index 9ede4e4..5a548d8 100644 --- a/lib/Feed.php +++ b/lib/Feed.php @@ -135,19 +135,19 @@ class Feed { // id doesn't exist. $content = $f->content.$f->enclosureUrl.$f->enclosureType; // if the item link URL and item title are both equal to the feed link URL, then the item has neither a link URL nor a title - if ($f->url==$feed->siteUrl && $f->title==$feed->siteUrl) { + if ($f->url === $feed->siteUrl && $f->title === $feed->siteUrl) { $f->urlTitleHash = ""; } else { $f->urlTitleHash = hash('sha256', $f->url.$f->title); } // if the item link URL is equal to the feed link URL, it has no link URL; if there is additionally no content, these should not be hashed - if (!strlen($content) && $f->url==$feed->siteUrl) { + if (!strlen($content) && $f->url === $feed->siteUrl) { $f->urlContentHash = ""; } else { $f->urlContentHash = hash('sha256', $f->url.$content); } // if the item's title is the same as its link URL, it has no title; if there is additionally no content, these should not be hashed - if (!strlen($content) && $f->title==$f->url) { + if (!strlen($content) && $f->title === $f->url) { $f->titleContentHash = ""; } else { $f->titleContentHash = hash('sha256', $f->title.$content); @@ -215,15 +215,15 @@ class Feed { foreach ($items as $item) { foreach ($out as $index => $check) { // if the two items both have IDs and they differ, they do not match, regardless of hashes - if ($item->id && $check->id && $item->id != $check->id) { + if ($item->id && $check->id && $item->id !== $check->id) { continue; } // if the two items have the same ID or any one hash matches, they are two versions of the same item if ( - ($item->id && $check->id && $item->id == $check->id) || - ($item->urlTitleHash && $item->urlTitleHash == $check->urlTitleHash) || - ($item->urlContentHash && $item->urlContentHash == $check->urlContentHash) || - ($item->titleContentHash && $item->titleContentHash == $check->titleContentHash) + ($item->id && $check->id && $item->id === $check->id) || + ($item->urlTitleHash && $item->urlTitleHash === $check->urlTitleHash) || + ($item->urlContentHash && $item->urlContentHash === $check->urlContentHash) || + ($item->titleContentHash && $item->titleContentHash === $check->titleContentHash) ) { if (// because newsfeeds are usually order newest-first, the later item should only be used if... // the later item has an update date and the existing item does not @@ -346,9 +346,9 @@ class Feed { $diff = $dates[$a] - $dates[$a+1]; $offsets[] = $this->normalizeDateDiff($diff); } - if ($offsets[0]==$offsets[1] || $offsets[0]==$offsets[2]) { + if ($offsets[0] === $offsets[1] || $offsets[0] === $offsets[2]) { return $now->modify("+".$offsets[0]); - } elseif ($offsets[1]==$offsets[2]) { + } elseif ($offsets[1] === $offsets[2]) { return $now->modify("+".$offsets[1]); } else { return $now->modify("+ 1 hour"); diff --git a/lib/Lang.php b/lib/Lang.php index a6e0735..66687ae 100644 --- a/lib/Lang.php +++ b/lib/Lang.php @@ -37,14 +37,14 @@ class Lang { $this->checkRequirements(); } // if requesting the same locale as already wanted, just return (but load first if we've requested an immediate load) - if ($locale==$this->wanted) { + if ($locale === $this->wanted) { if ($immediate && !$this->synched) { $this->load(); } return $locale; } // if we've requested a locale other than the null locale, fetch the list of available files and find the closest match e.g. en_ca_somedialect -> en_ca - if ($locale != "") { + if ($locale !== "") { $list = $this->listFiles(); // if the default locale is unavailable, this is (for now) an error if (!in_array(self::DEFAULT, $list)) { @@ -81,7 +81,7 @@ class Lang { try { $this->load(); } catch (Lang\Exception $e) { - if ($this->wanted==self::DEFAULT) { + if ($this->wanted === self::DEFAULT) { $this->set("", true); } else { throw $e; @@ -112,14 +112,14 @@ class Lang { $out = []; $files = $this->listFiles(); foreach ($files as $tag) { - $out[$tag] = \Locale::getDisplayName($tag, ($locale=="") ? $tag : $locale); + $out[$tag] = \Locale::getDisplayName($tag, ($locale === "") ? $tag : $locale); } return $out; } public function match(string $locale, array $list = null): string { $list = $list ?? $this->listFiles(); - $default = ($this->locale=="") ? self::DEFAULT : $this->locale; + $default = ($this->locale === "") ? self::DEFAULT : $this->locale; return \Locale::lookup($list, $locale, true, $default); } @@ -155,7 +155,7 @@ class Lang { $this->checkRequirements(); } // if we've requested no locale (""), just load the fallback strings and return - if ($this->wanted=="") { + if ($this->wanted === "") { $this->strings = self::REQUIRED; $this->locale = $this->wanted; $this->synched = true; @@ -169,7 +169,7 @@ class Lang { $tag = array_pop($tags); } // include the default locale as the base if the most general locale requested is not the default - if ($tag != self::DEFAULT) { + if ($tag !== self::DEFAULT) { $files[] = self::DEFAULT; } // save the list of files to be loaded for later reference @@ -177,14 +177,14 @@ class Lang { // reduce the list of files to be loaded to the minimum necessary (e.g. if we go from "fr" to "fr_ca", we don't need to load "fr" or "en") $files = []; foreach ($loaded as $file) { - if ($file==$this->locale) { + if ($file === $this->locale) { break; } $files[] = $file; } // if we need to load all files, start with the fallback strings $strings = []; - if ($files==$loaded) { + if ($files === $loaded) { $strings[] = self::REQUIRED; } else { // otherwise start with the strings we already have if we're going from e.g. "fr" to "fr_ca" diff --git a/lib/Misc/Date.php b/lib/Misc/Date.php index bf5e7a3..323b632 100644 --- a/lib/Misc/Date.php +++ b/lib/Misc/Date.php @@ -13,9 +13,9 @@ class Date { return null; } $out = ValueInfo::normalize($date, ValueInfo::T_STRING, null, $outFormat); - if ($outFormat=="unix") { + if ($outFormat === "unix") { $out = (int) $out; - } elseif ($outFormat=="float") { + } elseif ($outFormat === "float") { $out = (float) $out; } return $out; diff --git a/lib/Misc/ValueInfo.php b/lib/Misc/ValueInfo.php index 3f226f5..4d414a9 100644 --- a/lib/Misc/ValueInfo.php +++ b/lib/Misc/ValueInfo.php @@ -157,7 +157,7 @@ class ValueInfo { return $out; } else { $out = sprintf("%F", $value); - return substr($out, -2)==".0" ? (string) (int) $out : $out; + return preg_match("/\.0{1,}$/", $out) ? (string) (int) $out : $out; } } $info = self::str($value); @@ -189,7 +189,7 @@ class ValueInfo { try { if (!is_null($dateInFormat)) { $out = false; - if ($dateInFormat=="microtime") { + if ($dateInFormat === "microtime") { // PHP is not able to correctly handle the output of microtime() as the input of DateTime::createFromFormat(), so we fudge it to look like a float if (preg_match("<^0\.\d{6}00 \d+$>", $value)) { $value = substr($value, 11).".".substr($value, 2, 6); @@ -198,9 +198,9 @@ class ValueInfo { } } $f = isset(self::DATE_FORMATS[$dateInFormat]) ? self::DATE_FORMATS[$dateInFormat][0] : $dateInFormat; - if ($dateInFormat=="iso8601" || $dateInFormat=="iso8601m") { + if ($dateInFormat === "iso8601" || $dateInFormat === "iso8601m") { // DateTimeImmutable::createFromFormat() doesn't provide one catch-all for ISO 8601 timezone specifiers, so we try all of them till one works - if ($dateInFormat=="iso8601m") { + if ($dateInFormat === "iso8601m") { $f2 = self::DATE_FORMATS["iso8601"][0]; $zones = [$f."", $f."\Z", $f."P", $f."O", $f2."", $f2."\Z", $f2."P", $f2."O"]; } else { @@ -355,7 +355,7 @@ class ValueInfo { $out = filter_var($value, \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE); if (is_null($out) && (ValueInfo::int($value) & ValueInfo::VALID)) { $out = (int) filter_var($value, \FILTER_VALIDATE_FLOAT); - return ($out==1 || $out==0) ? (bool) $out : $default; + return ($out == 1 || $out == 0) ? (bool) $out : $default; } return !is_null($out) ? $out : $default; } diff --git a/lib/REST.php b/lib/REST.php index 70174c1..ed15060 100644 --- a/lib/REST.php +++ b/lib/REST.php @@ -76,7 +76,7 @@ class REST { // fetch the correct handler $drv = $this->getHandler($class); // generate a response - if ($req->getMethod()=="HEAD") { + if ($req->getMethod() === "HEAD") { // if the request is a HEAD request, we act exactly as if it were a GET request, and simply remove the response body later $res = $drv->dispatch($req->withMethod("GET")); } else { @@ -108,7 +108,7 @@ class REST { if (strpos($url, $api['match'])===0) { // if it matches, perform a more rigorous match and then strip off any defined prefix $pattern = "<^".preg_quote($api['match'])."([/\?#]|$)>"; - if ($url==$api['match'] || in_array(substr($api['match'], -1, 1), ["/", "?", "#"]) || preg_match($pattern, $url)) { + if ($url === $api['match'] || in_array(substr($api['match'], -1, 1), ["/", "?", "#"]) || preg_match($pattern, $url)) { $target = substr($url, strlen($api['strip'])); } else { // if the match fails we are not able to handle the request @@ -152,13 +152,13 @@ class REST { public function normalizeResponse(ResponseInterface $res, RequestInterface $req = null): ResponseInterface { // if the response code is 401, issue an HTTP authentication challenge - if ($res->getStatusCode()==401) { + if ($res->getStatusCode() == 401) { $res = $this->challenge($res); } // set or clear the Content-Length header field $body = $res->getBody(); $bodySize = $body->getSize(); - if ($bodySize || $res->getStatusCode()==200) { + if ($bodySize || $res->getStatusCode() == 200) { // if there is a message body or the response is 200, make sure Content-Length is included $res = $res->withHeader("Content-Length", (string) $bodySize); } else { @@ -166,7 +166,7 @@ class REST { $res = $res->withoutHeader("Content-Length"); } // if the response is to a HEAD request, the body should be omitted - if ($req && $req->getMethod()=="HEAD") { + if ($req && $req->getMethod() === "HEAD") { $res = new EmptyResponse($res->getStatusCode(), $res->getHeaders()); } // if an Allow header field is present, normalize it @@ -190,7 +190,7 @@ class REST { } public function corsApply(ResponseInterface $res, RequestInterface $req = null): ResponseInterface { - if ($req && $req->getMethod()=="OPTIONS") { + if ($req && $req->getMethod() === "OPTIONS") { if ($res->hasHeader("Allow")) { $res = $res->withHeader("Access-Control-Allow-Methods", $res->getHeaderLine("Allow")); } @@ -211,12 +211,12 @@ class REST { if ($allowed) { // continue if the request has exactly one Origin header $origin = $req->getHeader("Origin"); - if (sizeof($origin)==1) { + if (sizeof($origin) == 1) { // continue if the origin is syntactically valid $origin = $this->corsNormalizeOrigin($origin[0]); if ($origin) { // the special "null" origin should not be matched by the wildcard origin - $null = ($origin=="null"); + $null = ($origin === "null"); // pad all strings for simpler comparison $allowed = " ".$allowed." "; $denied = " ".$denied." "; @@ -243,7 +243,7 @@ class REST { public function corsNormalizeOrigin(string $origin, array $ports = null): string { $origin = trim($origin); - if ($origin=="null") { + if ($origin === "null") { // if the origin is the special value "null", use it return "null"; } @@ -259,7 +259,7 @@ class REST { // if the normalized port contains anything but numbers, or the scheme does not follow the generic URL syntax, the origin is invalid return ""; } - if ($host[0]=="[") { + if ($host[0] === "[") { // if the host appears to be an IPv6 address, validate it $host = rawurldecode(substr($host, 1, strlen($host) - 2)); if (!filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { @@ -279,7 +279,7 @@ class REST { if (strlen($port)) { $port = (int) substr($port, 1); $list = array_merge($ports ?? [], self::DEFAULT_PORTS); - if (isset($list[$scheme]) && $port==$list[$scheme]) { + if (isset($list[$scheme]) && $port == $list[$scheme]) { $port = ""; } else { $port = ":".$port; diff --git a/lib/REST/AbstractHandler.php b/lib/REST/AbstractHandler.php index b1c74bb..6060da4 100644 --- a/lib/REST/AbstractHandler.php +++ b/lib/REST/AbstractHandler.php @@ -28,7 +28,7 @@ abstract class AbstractHandler implements Handler { protected function fieldMapTypes(array $data, array $map, string $dateFormat = "sql"): array { foreach ($map as $key => $type) { if (array_key_exists($key, $data)) { - if ($type=="datetime" && $dateFormat != "sql") { + if ($type === "datetime" && $dateFormat !== "sql") { $data[$key] = Date::transform($data[$key], $dateFormat, "sql"); } else { settype($data[$key], $type); diff --git a/lib/REST/NextCloudNews/V1_2.php b/lib/REST/NextCloudNews/V1_2.php index f16d453..84beda3 100644 --- a/lib/REST/NextCloudNews/V1_2.php +++ b/lib/REST/NextCloudNews/V1_2.php @@ -88,7 +88,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler { // explode and normalize the URL path $target = new Target($req->getRequestTarget()); // handle HTTP OPTIONS requests - if ($req->getMethod()=="OPTIONS") { + if ($req->getMethod() === "OPTIONS") { return $this->handleHTTPOptions((string) $target); } // normalize the input @@ -104,7 +104,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler { return new EmptyResponse(415, ['Accept' => "application/json"]); } $data = @json_decode($data, true); - if (json_last_error() != \JSON_ERROR_NONE) { + if (json_last_error() !== \JSON_ERROR_NONE) { // if the body could not be parsed as JSON, return "400 Bad Request" return new EmptyResponse(400); } @@ -612,7 +612,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler { $c = new Context; $c->edition((int) $url[1]); // determine whether to mark read or unread - $set = ($url[2]=="read"); + $set = ($url[2] === "read"); try { Arsse::$db->articleMark(Arsse::$user->id, ['read' => $set], $c); } catch (ExceptionInput $e) { @@ -628,7 +628,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler { $c = new Context; $c->article((int) $url[2]); // determine whether to mark read or unread - $set = ($url[3]=="star"); + $set = ($url[3] ==="star"); try { Arsse::$db->articleMark(Arsse::$user->id, ['starred' => $set], $c); } catch (ExceptionInput $e) { @@ -641,7 +641,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler { // mark an array of articles as read protected function articleMarkReadMulti(array $url, array $data): ResponseInterface { // determine whether to mark read or unread - $set = ($url[1]=="read"); + $set = ($url[1] ==="read"); // initialize the matching context $c = new Context; $c->editions($data['items'] ?? []); @@ -655,7 +655,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler { // mark an array of articles as starred protected function articleMarkStarredMulti(array $url, array $data): ResponseInterface { // determine whether to mark starred or unstarred - $set = ($url[1]=="star"); + $set = ($url[1] ==="star"); // initialize the matching context $c = new Context; $c->articles(array_column($data['items'] ?? [], "guidHash")); diff --git a/lib/REST/Target.php b/lib/REST/Target.php index c3e28fe..b3fb94d 100644 --- a/lib/REST/Target.php +++ b/lib/REST/Target.php @@ -31,9 +31,9 @@ class Target { } else { continue; } - } elseif ($segment==".") { + } elseif ($segment === ".") { $path[] = "%2E"; - } elseif ($segment=="..") { + } elseif ($segment === "..") { $path[] = "%2E%2E"; } else { $path[] = rawurlencode(ValueInfo::normalize($segment, ValueInfo::T_STRING)); @@ -86,7 +86,7 @@ class Target { // note that the function assumes any fragment identifier or query has already been stripped off // syntax-based normalization is applied to the path segments (see RFC 3986 sec. 6.2.2) // duplicate slashes are NOT collapsed - if (substr($target, 0, 1)=="/") { + if (substr($target, 0, 1) === "/") { // if the path starts with a slash, strip it off $target = substr($target, 1); } else { @@ -96,7 +96,7 @@ class Target { if (!strlen($target)) { // if the target is an empty string, this is an index target $this->index = true; - } elseif (substr($target, -1, 1)=="/") { + } elseif (substr($target, -1, 1) === "/") { // if the path ends in a slash, this is an index target and the slash should be stripped off $this->index = true; $target = substr($target, 0, strlen($target) -1); @@ -107,11 +107,11 @@ class Target { $out = []; // resolve relative path segments and decode each retained segment foreach ($target as $index => $segment) { - if ($segment==".") { + if ($segment === ".") { // self-referential segments can be ignored continue; - } elseif ($segment=="..") { - if ($index==0) { + } elseif ($segment === "..") { + if ($index == 0) { // if the first path segment refers to its parent (which we don't know about) we cannot output a correct path, so we do the best we can $out[] = null; } else { diff --git a/lib/REST/TinyTinyRSS/API.php b/lib/REST/TinyTinyRSS/API.php index 014bbd6..de8b6b3 100644 --- a/lib/REST/TinyTinyRSS/API.php +++ b/lib/REST/TinyTinyRSS/API.php @@ -96,7 +96,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { // reject paths other than the index return new EmptyResponse(404); } - if ($req->getMethod()=="OPTIONS") { + if ($req->getMethod() === "OPTIONS") { // respond to OPTIONS rquests; the response is a fib, as we technically accept any type or method return new EmptyResponse(204, [ 'Allow' => "POST", @@ -107,7 +107,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { if ($data) { // only JSON entities are allowed, but Content-Type is ignored, as is request method $data = @json_decode($data, true); - if (json_last_error() != \JSON_ERROR_NONE || !is_array($data)) { + if (json_last_error() !== \JSON_ERROR_NONE || !is_array($data)) { return new Response(self::FATAL_ERR); } try { @@ -125,7 +125,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { // otherwise if HTTP authentication failed or is required, deny access at the HTTP level return new EmptyResponse(401); } - if (strtolower((string) $data['op']) != "login") { + if (strtolower((string) $data['op']) !== "login") { // unless logging in, a session identifier is required $this->resumeSession((string) $data['sid']); } @@ -432,7 +432,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { protected function enumerateFeeds(array $subs, $parent = null): array { $out = []; foreach ($subs as $s) { - if ($s['folder'] != $parent) { + if ($s['folder'] !== $parent) { continue; } $out[] = [ @@ -455,7 +455,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { $out = []; $feedTotal = 0; foreach ($cats as $c) { - if ($c['parent'] != $parent || (!$all && !($c['children'] + $c['feeds']))) { + if ($c['parent'] !== $parent || (!$all && !($c['children'] + $c['feeds']))) { // if the category is the wrong level, or if it's empty and we're not including empties, skip it continue; } @@ -546,7 +546,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { // transform the result and return $out = []; for ($a = 0; $a < sizeof($cats); $a++) { - if ($cats[$a]['id']==-2) { + if ($cats[$a]['id'] == -2) { // the Labels category has its unread count as a string in TTRSS (don't ask me why) settype($cats[$a]['unread'], "string"); } @@ -573,7 +573,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { // retrieve the ID of the existing folder; duplicating a folder silently returns the existing one $folders = Arsse::$db->folderList(Arsse::$user->id, $in['parent'], false); foreach ($folders as $folder) { - if ($folder['name']==$in['name']) { + if ($folder['name'] === $in['name']) { return (string) ((int) $folder['id']); // output is a string in TTRSS } } @@ -657,7 +657,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { $subs = []; $count = 0; // if the category is the special Labels category or the special All category (which includes labels), add labels to the list - if ($cat==self::CAT_ALL || $cat==self::CAT_LABELS) { + if ($cat == self::CAT_ALL || $cat == self::CAT_LABELS) { // NOTE: unused labels are not included foreach (Arsse::$db->labelList($user, false) as $l) { if ($unread && !$l['unread']) { @@ -672,7 +672,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { } } // if the category is the special Special (!) category or the special All category (which includes "special" feeds), add those feeds to the list - if ($cat==self::CAT_ALL || $cat==self::CAT_SPECIAL) { + if ($cat == self::CAT_ALL || $cat == self::CAT_SPECIAL) { // gather some statistics $starred = Arsse::$db->articleStarred($user)['unread']; $fresh = Arsse::$db->articleCount($user, (new Context)->unread(true)->modifiedSince(Date::sub("PT24H"))); @@ -754,10 +754,10 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { } } try { - if ($cat==self::CAT_NOT_SPECIAL || $cat==self::CAT_ALL) { + if ($cat == self::CAT_NOT_SPECIAL || $cat == self::CAT_ALL) { // if the "All" or "Not Special" categories were selected this returns all subscription, to any depth $subs = Arsse::$db->subscriptionList($user, null, true); - } elseif ($cat==self::CAT_UNCATEGORIZED) { + } elseif ($cat == self::CAT_UNCATEGORIZED) { // the "Uncategorized" special category returns subscriptions in the root, without going deeper $subs = Arsse::$db->subscriptionList($user, null, false); } else { @@ -1005,7 +1005,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { // try to rename the folder Arsse::$db->labelPropertiesSet(Arsse::$user->id, $id, ['name' => $name]); } catch (ExceptionInput $e) { - if ($e->getCode()==10237) { + if ($e->getCode() == 10237) { // if the supplied ID was invalid, report an error; other errors are to be ignored throw new Exception("INCORRECT_USAGE"); } @@ -1352,12 +1352,12 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { $data['skip'] = null; } if ($data['include_header']) { - if ($data['skip'] > 0 && $data['order_by'] != "date_reverse") { + if ($data['skip'] > 0 && $data['order_by'] !== "date_reverse") { // when paginating the header returns the latest ("first") item ID in the full list; we get this ID here $data['skip'] = 0; $data['limit'] = 1; $firstID = ($this->fetchArticles($data, ["id"])->getRow() ?? ['id' => 0])['id']; - } elseif ($data['order_by']=="date_reverse") { + } elseif ($data['order_by'] === "date_reverse") { // the "date_reverse" sort order doesn't get a first ID because it's meaningless for ascending-order pagination (pages doesn't go stale) $firstID = 0; } else { diff --git a/lib/REST/TinyTinyRSS/Icon.php b/lib/REST/TinyTinyRSS/Icon.php index 678dc8c..0415bf2 100644 --- a/lib/REST/TinyTinyRSS/Icon.php +++ b/lib/REST/TinyTinyRSS/Icon.php @@ -23,7 +23,7 @@ class Icon extends \JKingWeb\Arsse\REST\AbstractHandler { // otherwise if HTTP authentication failed or did not occur when it is required, deny access at the HTTP level return new Response(401); } - if ($req->getMethod() != "GET") { + if ($req->getMethod() !== "GET") { // only GET requests are allowed return new Response(405, ['Allow' => "GET"]); } elseif (!preg_match("<^(\d+)\.ico$>", $req->getRequestTarget(), $match) || !((int) $match[1])) { diff --git a/tests/cases/CLI/TestCLI.php b/tests/cases/CLI/TestCLI.php index 789767a..c2a6b52 100644 --- a/tests/cases/CLI/TestCLI.php +++ b/tests/cases/CLI/TestCLI.php @@ -160,8 +160,8 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest { Arsse::$user = $this->createMock(User::class); Arsse::$user->method("auth")->will($this->returnCallback(function($user, $pass) { return ( - ($user == "john.doe@example.com" && $pass == "secret") || - ($user == "jane.doe@example.com" && $pass == "superman") + ($user === "john.doe@example.com" && $pass === "secret") || + ($user === "jane.doe@example.com" && $pass === "superman") ); })); $this->assertConsole($this->cli, $cmd, $exitStatus, $output); @@ -182,7 +182,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest { // FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead Arsse::$user = $this->createMock(User::class); Arsse::$user->method("remove")->will($this->returnCallback(function($user) { - if ($user == "john.doe@example.com") { + if ($user === "john.doe@example.com") { return true; } throw new \JKingWeb\Arsse\User\Exception("doesNotExist"); diff --git a/tests/cases/Db/BaseDriver.php b/tests/cases/Db/BaseDriver.php index 08f9634..402abbb 100644 --- a/tests/cases/Db/BaseDriver.php +++ b/tests/cases/Db/BaseDriver.php @@ -359,7 +359,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest { // SQLite is unaffected by the removal of the metadata table; other backends are // in neither case should a query for the schema version produce an error, however $this->exec("DROP TABLE IF EXISTS arsse_meta"); - $exp = (static::$dbInfo->backend == "SQLite 3") ? 2 : 0; + $exp = (static::$dbInfo->backend === "SQLite 3") ? 2 : 0; $this->assertSame($exp, $this->drv->schemaVersion()); } diff --git a/tests/cases/Db/BaseStatement.php b/tests/cases/Db/BaseStatement.php index 15abab3..c5d9155 100644 --- a/tests/cases/Db/BaseStatement.php +++ b/tests/cases/Db/BaseStatement.php @@ -58,7 +58,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest { /** @dataProvider provideBindings */ public function testBindATypedValue($value, string $type, string $exp) { - if ($exp=="null") { + if ($exp === "null") { $query = "SELECT (? is null) as pass"; } else { $query = "SELECT ($exp = ?) as pass"; @@ -75,7 +75,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest { if (in_array(static::$implementation, ["PostgreSQL", "PDO PostgreSQL"])) { $this->markTestSkipped("Correct handling of binary data with PostgreSQL is currently unknown"); } - if ($exp=="null") { + if ($exp === "null") { $query = "SELECT (? is null) as pass"; } else { $query = "SELECT ($exp = ?) as pass"; @@ -275,7 +275,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest { ]; foreach ($tests as $index => list($value, $type, $exp)) { $t = preg_replace("<^strict >", "", $type); - $exp = ($exp=="null") ? $exp : $this->decorateTypeSyntax($exp, $t); + $exp = ($exp === "null") ? $exp : $this->decorateTypeSyntax($exp, $t); yield $index => [$value, $type, $exp]; } } @@ -326,7 +326,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest { ]; foreach ($tests as $index => list($value, $type, $exp)) { $t = preg_replace("<^strict >", "", $type); - $exp = ($exp=="null") ? $exp : $this->decorateTypeSyntax($exp, $t); + $exp = ($exp === "null") ? $exp : $this->decorateTypeSyntax($exp, $t); yield $index => [$value, $type, $exp]; } } diff --git a/tests/cases/Db/MySQLPDO/TestStatement.php b/tests/cases/Db/MySQLPDO/TestStatement.php index f956302..02703a1 100644 --- a/tests/cases/Db/MySQLPDO/TestStatement.php +++ b/tests/cases/Db/MySQLPDO/TestStatement.php @@ -20,7 +20,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { protected function decorateTypeSyntax(string $value, string $type): string { switch ($type) { case "float": - return (substr($value, -2)==".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; + return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; case "string": if (preg_match("<^char\((\d+)\)$>", $value, $match)) { return "'".\IntlChar::chr((int) $match[1])."'"; diff --git a/tests/cases/Db/PostgreSQL/TestCreation.php b/tests/cases/Db/PostgreSQL/TestCreation.php index 182d3a3..720e32b 100644 --- a/tests/cases/Db/PostgreSQL/TestCreation.php +++ b/tests/cases/Db/PostgreSQL/TestCreation.php @@ -25,7 +25,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest { $timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0); $postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'"; $act = Driver::makeConnectionString($pdo, $user, $pass, $db, $host, $port, $service); - if ($act==$postfix) { + if ($act === $postfix) { $this->assertSame($exp, ""); } else { $test = substr($act, 0, strlen($act) - (strlen($postfix) + 1)); diff --git a/tests/cases/Db/PostgreSQL/TestStatement.php b/tests/cases/Db/PostgreSQL/TestStatement.php index e0e9b02..d5c770c 100644 --- a/tests/cases/Db/PostgreSQL/TestStatement.php +++ b/tests/cases/Db/PostgreSQL/TestStatement.php @@ -20,7 +20,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { protected function decorateTypeSyntax(string $value, string $type): string { switch ($type) { case "float": - return (substr($value, -2)==".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; + return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; case "string": if (preg_match("<^char\((\d+)\)$>", $value, $match)) { return "U&'\\+".str_pad(dechex((int) $match[1]), 6, "0", \STR_PAD_LEFT)."'"; diff --git a/tests/cases/Db/PostgreSQLPDO/TestCreation.php b/tests/cases/Db/PostgreSQLPDO/TestCreation.php index 83d95e8..a9babc1 100644 --- a/tests/cases/Db/PostgreSQLPDO/TestCreation.php +++ b/tests/cases/Db/PostgreSQLPDO/TestCreation.php @@ -25,7 +25,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest { $timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0); $postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'"; $act = Driver::makeConnectionString($pdo, $user, $pass, $db, $host, $port, $service); - if ($act==$postfix) { + if ($act === $postfix) { $this->assertSame($exp, ""); } else { $test = substr($act, 0, strlen($act) - (strlen($postfix) + 1)); diff --git a/tests/cases/Db/PostgreSQLPDO/TestStatement.php b/tests/cases/Db/PostgreSQLPDO/TestStatement.php index 900c2e8..571495d 100644 --- a/tests/cases/Db/PostgreSQLPDO/TestStatement.php +++ b/tests/cases/Db/PostgreSQLPDO/TestStatement.php @@ -20,7 +20,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { protected function decorateTypeSyntax(string $value, string $type): string { switch ($type) { case "float": - return (substr($value, -2)==".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; + return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; case "string": if (preg_match("<^char\((\d+)\)$>", $value, $match)) { return "U&'\\+".str_pad(dechex((int) $match[1]), 6, "0", \STR_PAD_LEFT)."'"; diff --git a/tests/cases/Db/SQLite3PDO/TestStatement.php b/tests/cases/Db/SQLite3PDO/TestStatement.php index 36f2eb9..b996676 100644 --- a/tests/cases/Db/SQLite3PDO/TestStatement.php +++ b/tests/cases/Db/SQLite3PDO/TestStatement.php @@ -17,8 +17,8 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { } protected function decorateTypeSyntax(string $value, string $type): string { - if ($type=="float") { - return (substr($value, -2)==".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; + if ($type === "float") { + return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; } else { return $value; } diff --git a/tests/cases/REST/TinyTinyRSS/TestAPI.php b/tests/cases/REST/TinyTinyRSS/TestAPI.php index 8ba992b..d242269 100644 --- a/tests/cases/REST/TinyTinyRSS/TestAPI.php +++ b/tests/cases/REST/TinyTinyRSS/TestAPI.php @@ -350,7 +350,7 @@ LONG_STRING; 'userSessionEnforced' => false, ]; $http401 = new EmptyResponse(401); - if ($type=="login") { + if ($type === "login") { return [ // conf, user, data, result [$defaults, null, $johnGood, $johnSess], @@ -474,7 +474,7 @@ LONG_STRING; [$fullHttp, "", $missingU, $http401], [$fullHttp, "", $missingP, $http401], ]; - } elseif ($type=="isLoggedIn") { + } elseif ($type === "isLoggedIn") { return [ // conf, user, session, result [$defaults, null, $sidJohn, $john], @@ -1517,13 +1517,13 @@ LONG_STRING; protected function filterFolders(int $id = null): array { return array_filter($this->folders, function($value) use ($id) { - return $value['parent']==$id; + return $value['parent'] == $id; }); } protected function filterSubs(int $folder = null): array { return array_filter($this->subscriptions, function($value) use ($folder) { - return $value['folder']==$folder; + return $value['folder'] == $folder; }); } @@ -1533,7 +1533,7 @@ LONG_STRING; $out += $this->reduceFolders($f['id']); } $out += array_reduce(array_filter($this->subscriptions, function($value) use ($id) { - return $value['folder']==$id; + return $value['folder'] == $id; }), function($sum, $value) { return $sum + $value['unread']; }, 0); diff --git a/tests/cases/User/TestUser.php b/tests/cases/User/TestUser.php index abe4b5a..9496c41 100644 --- a/tests/cases/User/TestUser.php +++ b/tests/cases/User/TestUser.php @@ -60,7 +60,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest { $this->assertSame($exp, $u->auth($user, $password)); $this->assertNull($u->id); Phake::verify(Arsse::$db, Phake::times($exp ? 1 : 0))->userExists($user); - Phake::verify(Arsse::$db, Phake::times($exp && $user == "jane.doe@example.com" ? 1 : 0))->userAdd($user, $password); + Phake::verify(Arsse::$db, Phake::times($exp && $user === "jane.doe@example.com" ? 1 : 0))->userAdd($user, $password); } public function provideAuthentication() { @@ -274,7 +274,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest { } finally { Phake::verify($this->drv, Phake::times($calls))->userPasswordSet; Phake::verify($u, Phake::times($calls / 2))->generatePassword; - Phake::verify(Arsse::$db, Phake::times($calls==4 ? 2 : 0))->userExists($user); + Phake::verify(Arsse::$db, Phake::times($calls == 4 ? 2 : 0))->userExists($user); if ($calls == 4) { Phake::verify(Arsse::$db, Phake::times($exists ? 1 : 0))->userPasswordSet($user, $pass1, null); Phake::verify(Arsse::$db, Phake::times($exists ? 1 : 0))->userPasswordSet($user, $pass2, null); diff --git a/tests/lib/DatabaseInformation.php b/tests/lib/DatabaseInformation.php index 6a5322f..4f8636c 100644 --- a/tests/lib/DatabaseInformation.php +++ b/tests/lib/DatabaseInformation.php @@ -83,7 +83,7 @@ class DatabaseInformation { } catch (\Throwable $e) { } foreach ($sqlite3TableList($db) as $table) { - if ($table == "arsse_meta") { + if ($table === "arsse_meta") { $db->exec("DELETE FROM $table where key <> 'schema_version'"); } else { $db->exec("DELETE FROM $table"); @@ -137,9 +137,9 @@ class DatabaseInformation { } catch (\Throwable $e) { } foreach ($pgObjectList($db) as $obj) { - if ($obj['type'] != "TABLE") { + if ($obj['type'] !== "TABLE") { continue; - } elseif ($obj['name'] == "arsse_meta") { + } elseif ($obj['name'] === "arsse_meta") { $pgExecFunction($db, "DELETE FROM {$obj['name']} where key <> 'schema_version'"); } else { $pgExecFunction($db, "TRUNCATE TABLE {$obj['name']} restart identity cascade"); @@ -181,7 +181,7 @@ class DatabaseInformation { } catch (\Throwable $e) { } foreach ($mysqlTableList($db) as $table) { - if ($table == "arsse_meta") { + if ($table === "arsse_meta") { $db->query("DELETE FROM $table where `key` <> 'schema_version'"); } else { $db->query("DELETE FROM $table");