From c30b24d09f4096e612965af658540595262f6848 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Fri, 30 Dec 2022 19:51:34 +0300 Subject: [PATCH] deal with type errors in batch feed editor properly, un-deprecate PDO wrapper functions and document them for posterity --- classes/handler/public.php | 2 +- classes/pref/feeds.php | 12 ++++++------ classes/pref/filters.php | 16 ++++++++-------- include/functions.php | 13 ++++++++----- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/classes/handler/public.php b/classes/handler/public.php index 190c806be..c6ec39f36 100755 --- a/classes/handler/public.php +++ b/classes/handler/public.php @@ -381,7 +381,7 @@ class Handler_Public extends Handler { $login = clean($_POST["login"]); $password = clean($_POST["password"]); $remember_me = clean($_POST["remember_me"] ?? false); - $safe_mode = checkbox_to_sql_bool(clean($_POST["safe_mode"] ?? false)); + $safe_mode = checkbox_to_sql_bool($_POST["safe_mode"] ?? false); if (session_status() != PHP_SESSION_ACTIVE) { if ($remember_me) { diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index d2fcdc804..679eb12e9 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -713,12 +713,12 @@ class Pref_Feeds extends Handler_Protected { $cat_id = (int) clean($_POST["cat_id"] ?? 0); $auth_login = clean($_POST["auth_login"] ?? ""); $auth_pass = clean($_POST["auth_pass"] ?? ""); - $private = clean($_POST["private"] ?? "") == "on"; - $include_in_digest = clean($_POST["include_in_digest"] ?? "") == "on"; - $cache_images = clean($_POST["cache_images"] ?? "") == "on"; - $hide_images = clean($_POST["hide_images"] ?? "") == "on"; - $always_display_enclosures = clean($_POST["always_display_enclosures"] ?? "") == "on"; - $mark_unread_on_update = clean($_POST["mark_unread_on_update"] ?? "") == "on"; + $private = checkbox_to_sql_bool($_POST["private"] ?? ""); + $include_in_digest = checkbox_to_sql_bool($_POST["include_in_digest"] ?? ""); + $cache_images = checkbox_to_sql_bool($_POST["cache_images"] ?? ""); + $hide_images = checkbox_to_sql_bool($_POST["hide_images"] ?? ""); + $always_display_enclosures = checkbox_to_sql_bool($_POST["always_display_enclosures"] ?? ""); + $mark_unread_on_update = checkbox_to_sql_bool($_POST["mark_unread_on_update"] ?? ""); $feed_language = clean($_POST["feed_language"] ?? ""); diff --git a/classes/pref/filters.php b/classes/pref/filters.php index 19ec8d39e..2656c0370 100755 --- a/classes/pref/filters.php +++ b/classes/pref/filters.php @@ -57,8 +57,8 @@ class Pref_Filters extends Handler_Protected { $filter = array(); $filter["enabled"] = true; - $filter["match_any_rule"] = checkbox_to_sql_bool(clean($_REQUEST["match_any_rule"] ?? false)); - $filter["inverse"] = checkbox_to_sql_bool(clean($_REQUEST["inverse"] ?? false)); + $filter["match_any_rule"] = checkbox_to_sql_bool($_REQUEST["match_any_rule"] ?? false); + $filter["inverse"] = checkbox_to_sql_bool($_REQUEST["inverse"] ?? false); $filter["rules"] = array(); $filter["actions"] = array("dummy-action"); @@ -511,9 +511,9 @@ class Pref_Filters extends Handler_Protected { function editSave(): void { $filter_id = (int) clean($_REQUEST["id"]); - $enabled = checkbox_to_sql_bool(clean($_REQUEST["enabled"] ?? false)); - $match_any_rule = checkbox_to_sql_bool(clean($_REQUEST["match_any_rule"] ?? false)); - $inverse = checkbox_to_sql_bool(clean($_REQUEST["inverse"] ?? false)); + $enabled = checkbox_to_sql_bool($_REQUEST["enabled"] ?? false); + $match_any_rule = checkbox_to_sql_bool($_REQUEST["match_any_rule"] ?? false); + $inverse = checkbox_to_sql_bool($_REQUEST["inverse"] ?? false); $title = clean($_REQUEST["title"]); $this->pdo->beginTransaction(); @@ -624,10 +624,10 @@ class Pref_Filters extends Handler_Protected { } function add(): void { - $enabled = checkbox_to_sql_bool(clean($_REQUEST["enabled"] ?? false)); - $match_any_rule = checkbox_to_sql_bool(clean($_REQUEST["match_any_rule"] ?? false)); + $enabled = checkbox_to_sql_bool($_REQUEST["enabled"] ?? false); + $match_any_rule = checkbox_to_sql_bool($_REQUEST["match_any_rule"] ?? false); $title = clean($_REQUEST["title"]); - $inverse = checkbox_to_sql_bool(clean($_REQUEST["inverse"] ?? false)); + $inverse = checkbox_to_sql_bool($_REQUEST["inverse"] ?? false); $this->pdo->beginTransaction(); diff --git a/include/functions.php b/include/functions.php index 403c96b85..0d7f8c756 100644 --- a/include/functions.php +++ b/include/functions.php @@ -357,9 +357,11 @@ return $s && ($s !== "f" && $s !== "false"); //no-op for PDO, backwards compat for legacy layer } - /** @deprecated misleading name, seems to be pointless wrapper */ + /** workaround for PDO casting all query parameters to string unless type is specified explicitly, + * which breaks booleans having false value because they become empty string literals ("") causing + * DB type mismatches and breaking SQL queries */ function bool_to_sql_bool(bool $s): int { - return $s ? 1 : 0; + return (int)$s; } function file_is_locked(string $filename): bool { @@ -411,12 +413,13 @@ } } - /** + /** checkbox-specific workaround for PDO casting all query parameters to string unless type is + * specified explicitly, which breaks booleans having false value because they become empty + * string literals ("") causing DB type mismatches and breaking SQL queries * @param mixed $val - * @deprecated misleading name, seems to be a pointless wrapper */ function checkbox_to_sql_bool($val): int { - return ($val == "on") ? 1 : 0; + return ($val === "on") ? 1 : 0; } function uniqid_short(): string {