From b6e1a5c91a0999a13eda4207fc23ff495637d697 Mon Sep 17 00:00:00 2001
From: Andrew Dolgov <noreply@fakecake.org>
Date: Sat, 6 Feb 2021 17:19:07 +0300
Subject: [PATCH] fix several warnings reported by phpstan

---
 classes/feeds.php      | 21 ++++++++++----------
 classes/rpc.php        | 10 +++++-----
 classes/rssutils.php   | 20 ++++++++++---------
 classes/sanitizer.php  |  8 ++++----
 classes/timehelper.php |  3 ++-
 classes/urlhelper.php  | 44 +++++++++++++++++++++---------------------
 install/index.php      |  4 ++--
 7 files changed, 57 insertions(+), 53 deletions(-)

diff --git a/classes/feeds.php b/classes/feeds.php
index 6a4bd5fcd..194a41c98 100755
--- a/classes/feeds.php
+++ b/classes/feeds.php
@@ -115,10 +115,9 @@ class Feeds extends Handler_Protected {
 
 		$this->mark_timestamp("init");
 
-		$reply = array();
-
-		$rgba_cache = array();
-		$topmost_article_ids = array();
+		$reply = [];
+		$rgba_cache = [];
+		$topmost_article_ids = [];
 
 		if (!$offset) $offset = 0;
 		if ($method == "undefined") $method = "";
@@ -154,6 +153,8 @@ class Feeds extends Handler_Protected {
 			$disable_cache = true;
 		}
 
+		$qfh_ret = [];
+
 		if (!$cat_view && is_numeric($feed) && $feed < PLUGIN_FEED_BASE_INDEX && $feed > LABEL_BASE_INDEX) {
 			$handler = PluginHost::getInstance()->get_feed_handler(
 				PluginHost::feed_to_pfeed_id($feed));
@@ -220,19 +221,19 @@ class Feeds extends Handler_Protected {
 			$feed, $cat_view, $search,
 			$last_error, $last_updated);
 
+		$reply['content'] = [];
+
 		if ($offset == 0) {
 			foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINES_BEFORE) as $p) {
 				 $reply['content'] .= $p->hook_headlines_before($feed, $cat_view, $qfh_ret);
 			}
 		}
 
-		$reply['content'] = [];
-
 		$this->mark_timestamp("object header");
 
 		$headlines_count = 0;
 
-        if (is_object($result)) {
+		if ($result instanceof PDOStatement) {
 			while ($line = $result->fetch(PDO::FETCH_ASSOC)) {
 				$this->mark_timestamp("article start: " . $line["id"] . " " . $line["title"]);
 
@@ -363,7 +364,7 @@ class Feeds extends Handler_Protected {
 				else
 					$tags = false;
 
-				$line["tags_str"] = Article::format_tags_string($tags, $id);
+				$line["tags_str"] = Article::format_tags_string($tags);
 
 				$this->mark_timestamp("   tags");
 
@@ -410,7 +411,7 @@ class Feeds extends Handler_Protected {
 
 		if (!$headlines_count) {
 
-			if (is_object($result)) {
+			if ($result instanceof PDOStatement) {
 
 				if ($query_error_override) {
 					$message = $query_error_override;
@@ -1087,7 +1088,7 @@ class Feeds extends Handler_Protected {
 		} else if ($n_feed >= 0) {
 
 			if ($n_feed != 0) {
-				$match_part = "feed_id = " . (int)$n_feed;
+				$match_part = sprintf("feed_id = %d", $n_feed);
 			} else {
 				$match_part = "feed_id IS NULL";
 			}
diff --git a/classes/rpc.php b/classes/rpc.php
index 57bea0bbe..9f86c9401 100755
--- a/classes/rpc.php
+++ b/classes/rpc.php
@@ -244,7 +244,7 @@ class RPC extends Handler_Protected {
 	function setpanelmode() {
 		$wide = (int) clean($_REQUEST["wide"]);
 
-		setcookie("ttrss_widescreen", $wide,
+		setcookie("ttrss_widescreen", (string)$wide,
 			time() + COOKIE_LIFETIME_LONG);
 
 		print json_encode(array("wide" => $wide));
@@ -462,7 +462,7 @@ class RPC extends Handler_Protected {
 		$params["default_view_order_by"] = get_pref("_DEFAULT_VIEW_ORDER_BY");
 		$params["bw_limit"] = (int) $_SESSION["bw_limit"];
 		$params["is_default_pw"] = Pref_Prefs::isdefaultpassword();
-		$params["label_base_index"] = (int) LABEL_BASE_INDEX;
+		$params["label_base_index"] = LABEL_BASE_INDEX;
 
 		$theme = get_pref( "USER_CSS_THEME", false, false);
 		$params["theme"] = theme_exists($theme) ? $theme : "";
@@ -490,7 +490,7 @@ class RPC extends Handler_Protected {
 
 		$params["widescreen"] = (int) ($_COOKIE["ttrss_widescreen"] ?? 0);
 
-		$params['simple_update'] = defined('SIMPLE_UPDATE_MODE') && SIMPLE_UPDATE_MODE;
+		$params['simple_update'] = SIMPLE_UPDATE_MODE;
 
 		$params["icon_indicator_white"] = $this->image_to_base64("images/indicator_white.gif");
 
@@ -503,7 +503,7 @@ class RPC extends Handler_Protected {
 		if (file_exists($filename)) {
 			$ext = pathinfo($filename, PATHINFO_EXTENSION);
 
-			return "data:image/$ext;base64," . base64_encode(file_get_contents($filename));
+			return "data:image/$ext;base64," . base64_encode((string)file_get_contents($filename));
 		} else {
 			return "";
 		}
@@ -719,7 +719,7 @@ class RPC extends Handler_Protected {
 		$prefixes = array();
 
 		foreach (array_keys($hotkeys) as $hotkey) {
-			$pair = explode(" ", $hotkey, 2);
+			$pair = explode(" ", (string)$hotkey, 2);
 
 			if (count($pair) > 1 && !in_array($pair[0], $prefixes)) {
 				array_push($prefixes, $pair[0]);
diff --git a/classes/rssutils.php b/classes/rssutils.php
index 8a1ab6bbc..45cddb200 100755
--- a/classes/rssutils.php
+++ b/classes/rssutils.php
@@ -1415,7 +1415,7 @@ class RSSUtils {
 	 * @param    string    query
 	 * @return    array    params
 	 */
-	static function convertUrlQuery($query) {
+	/* static function convertUrlQuery($query) {
 		$queryParts = explode('&', $query);
 
 		$params = array();
@@ -1426,7 +1426,7 @@ class RSSUtils {
 		}
 
 		return $params;
-	}
+	} */
 
 	static function get_article_filters($filters, $title, $content, $link, $author, $tags, &$matched_rules = false, &$matched_filters = false) {
 		$matches = array();
@@ -1435,14 +1435,16 @@ class RSSUtils {
 			$match_any_rule = $filter["match_any_rule"];
 			$inverse = $filter["inverse"];
 			$filter_match = false;
+			$last_processed_rule = false;
 
 			foreach ($filter["rules"] as $rule) {
 				$match = false;
-				$reg_exp = str_replace('/', '\/', $rule["reg_exp"]);
+				$reg_exp = str_replace('/', '\/', (string)$rule["reg_exp"]);
 				$reg_exp = str_replace("\n", "", $reg_exp); // reg_exp may be formatted with CRs now because of textarea, we need to strip those
 				$rule_inverse = $rule["inverse"];
+				$last_processed_rule = $rule;
 
-				if (!$reg_exp)
+				if (empty($reg_exp))
 					continue;
 
 				switch ($rule["type"]) {
@@ -1451,13 +1453,13 @@ class RSSUtils {
 						break;
 					case "content":
 						// we don't need to deal with multiline regexps
-						$content = preg_replace("/[\r\n\t]/", "", $content);
+						$content = (string)preg_replace("/[\r\n\t]/", "", $content);
 
 						$match = @preg_match("/$reg_exp/iu", $content);
 						break;
 					case "both":
 						// we don't need to deal with multiline regexps
-						$content = preg_replace("/[\r\n\t]/", "", $content);
+						$content = (string)preg_replace("/[\r\n\t]/", "", $content);
 
 						$match = (@preg_match("/$reg_exp/iu", $title) || @preg_match("/$reg_exp/iu", $content));
 						break;
@@ -1495,7 +1497,7 @@ class RSSUtils {
 			if ($inverse) $filter_match = !$filter_match;
 
 			if ($filter_match) {
-				if (is_array($matched_rules)) array_push($matched_rules, $rule);
+				if (is_array($matched_rules)) array_push($matched_rules, $last_processed_rule);
 				if (is_array($matched_filters)) array_push($matched_filters, $filter);
 
 				foreach ($filter["actions"] AS $action) {
@@ -1581,11 +1583,11 @@ class RSSUtils {
 
 			$pdo->beginTransaction();
 
-			$days = (int) DAEMON_UNSUCCESSFUL_DAYS_LIMIT;
+			$days = DAEMON_UNSUCCESSFUL_DAYS_LIMIT;
 
 			if (DB_TYPE == "pgsql") {
 				$interval_query = "last_successful_update < NOW() - INTERVAL '$days days' AND last_updated > NOW() - INTERVAL '1 days'";
-			} else if (DB_TYPE == "mysql") {
+			} else /* if (DB_TYPE == "mysql") */ {
 				$interval_query = "last_successful_update < DATE_SUB(NOW(), INTERVAL $days DAY) AND last_updated > DATE_SUB(NOW(), INTERVAL 1 DAY)";
 			}
 
diff --git a/classes/sanitizer.php b/classes/sanitizer.php
index 9ca4200a5..5a054c3b0 100644
--- a/classes/sanitizer.php
+++ b/classes/sanitizer.php
@@ -188,16 +188,16 @@ class Sanitizer {
 					$text = $child->textContent;
 
 					while (($pos = mb_stripos($text, $word)) !== false) {
-						$fragment->appendChild(new DomText(mb_substr($text, 0, $pos)));
-						$word = mb_substr($text, $pos, mb_strlen($word));
+						$fragment->appendChild(new DOMText(mb_substr($text, 0, (int)$pos)));
+						$word = mb_substr($text, (int)$pos, mb_strlen($word));
 						$highlight = $doc->createElement('span');
-						$highlight->appendChild(new DomText($word));
+						$highlight->appendChild(new DOMText($word));
 						$highlight->setAttribute('class', 'highlight');
 						$fragment->appendChild($highlight);
 						$text = mb_substr($text, $pos + mb_strlen($word));
 					}
 
-					if (!empty($text)) $fragment->appendChild(new DomText($text));
+					if (!empty($text)) $fragment->appendChild(new DOMText($text));
 
 					$child->parentNode->replaceChild($fragment, $child);
 				}
diff --git a/classes/timehelper.php b/classes/timehelper.php
index e9bd36cad..7dff71669 100644
--- a/classes/timehelper.php
+++ b/classes/timehelper.php
@@ -82,7 +82,8 @@ class TimeHelper {
 		}
 
 		$dt = new DateTime(date('Y-m-d H:i:s', $timestamp), $source_tz);
-		return $dt->format('U') + $dest_tz->getOffset($dt);
+
+		return (int)$dt->format('U') + $dest_tz->getOffset($dt);
 	}
 
 }
diff --git a/classes/urlhelper.php b/classes/urlhelper.php
index ecb7ed67c..8717d02c3 100644
--- a/classes/urlhelper.php
+++ b/classes/urlhelper.php
@@ -237,6 +237,8 @@ class UrlHelper {
 
 			$ch = curl_init($url);
 
+			if (!$ch) return false;
+
 			$curl_http_headers = [];
 
 			if ($last_modified && !$post_query)
@@ -361,7 +363,7 @@ class UrlHelper {
 
 			$is_gzipped = RSSUtils::is_gzipped($contents);
 
-			if ($is_gzipped) {
+			if ($is_gzipped && is_string($contents)) {
 				$tmp = @gzdecode($contents);
 
 				if ($tmp) $contents = $tmp;
@@ -433,29 +435,27 @@ class UrlHelper {
 
 			$data = @file_get_contents($url, false, $context);
 
-			if (isset($http_response_header) && is_array($http_response_header)) {
-				foreach ($http_response_header as $header) {
-					if (strstr($header, ": ") !== false) {
-						list ($key, $value) = explode(": ", $header);
-
-						$key = strtolower($key);
-
-						if ($key == 'content-type') {
-							$fetch_last_content_type = $value;
-							// don't abort here b/c there might be more than one
-							// e.g. if we were being redirected -- last one is the right one
-						} else if ($key == 'last-modified') {
-							$fetch_last_modified = $value;
-						} else if ($key == 'location') {
-							$fetch_effective_url = $value;
-						}
-					}
+			foreach ($http_response_header as $header) {
+				if (strstr($header, ": ") !== false) {
+					list ($key, $value) = explode(": ", $header);
+
+					$key = strtolower($key);
 
-					if (substr(strtolower($header), 0, 7) == 'http/1.') {
-						$fetch_last_error_code = (int) substr($header, 9, 3);
-						$fetch_last_error = $header;
+					if ($key == 'content-type') {
+						$fetch_last_content_type = $value;
+						// don't abort here b/c there might be more than one
+						// e.g. if we were being redirected -- last one is the right one
+					} else if ($key == 'last-modified') {
+						$fetch_last_modified = $value;
+					} else if ($key == 'location') {
+						$fetch_effective_url = $value;
 					}
 				}
+
+				if (substr(strtolower($header), 0, 7) == 'http/1.') {
+					$fetch_last_error_code = (int) substr($header, 9, 3);
+					$fetch_last_error = $header;
+				}
 			}
 
 			if ($fetch_last_error_code != 200) {
@@ -472,7 +472,7 @@ class UrlHelper {
 
 			$is_gzipped = RSSUtils::is_gzipped($data);
 
-			if ($is_gzipped) {
+			if ($is_gzipped && $data) {
 				$tmp = @gzdecode($data);
 
 				if ($tmp) $data = $tmp;
diff --git a/install/index.php b/install/index.php
index 0859fc4d7..9c696b21d 100644
--- a/install/index.php
+++ b/install/index.php
@@ -81,7 +81,7 @@
 	}
 
 
-	function sanity_check($db_type) {
+	function installer_sanity_check($db_type) {
 		$errors = array();
 
 		if (version_compare(PHP_VERSION, '7.0.0', '<')) {
@@ -278,7 +278,7 @@
 	<h2>Checking configuration</h2>
 
 	<?php
-		$errors = sanity_check($DB_TYPE);
+		$errors = installer_sanity_check($DB_TYPE);
 
 		if (count($errors) > 0) {
 			print "<p>Some configuration tests failed. Please correct them before continuing.</p>";
-- 
GitLab