diff --git a/inc/fw-update.php b/inc/fw-update.php index cc9b5e7e3..c5bb5d15a 100644 --- a/inc/fw-update.php +++ b/inc/fw-update.php @@ -722,12 +722,56 @@ function spbc_security_firewall_update__get_ips_count() '%t2' => SPBC_TBL_FIREWALL_DATA__IPS_V4 ]; $query_v4 = str_replace(array_keys($data), array_values($data), $query); - $data['%q'] = str_replace("%m", (string)$mask, "(%m - mask1) + (%m - mask2) + (%m - mask3) + (%m - mask4)"); - $data['%t1'] = SPBC_TBL_FIREWALL_DATA_V6; - $data['%t2'] = SPBC_TBL_FIREWALL_DATA__IPS_V6; - $query_v6 = str_replace(array_keys($data), array_values($data), $query); - return $wpdb->get_var($query_v4) + $wpdb->get_var($query_v6); + return (int)$wpdb->get_var($query_v4) + spbc_security_firewall_update__get_ipv6_ips_count(); +} + +/** + * Counts IPv6 addresses covered by a single firewall table. + * + * Mirrors IP::convertLongIntMaskToDec() in SQL to avoid loading all rows into PHP. + * Large prefixes (/0–/95) are excluded from host expansion. + * + * @param string $table + * + * @return int + */ +function spbc_security_firewall_update__get_ipv6_ips_count_for_table($table) +{ + global $wpdb; + + $allowed_tables = array( + SPBC_TBL_FIREWALL_DATA_V6, + SPBC_TBL_FIREWALL_DATA__IPS_V6, + ); + if ( ! in_array($table, $allowed_tables, true) ) { + return 0; + } + + $sql = 'SELECT COALESCE(SUM( + CASE + WHEN prefix = 128 THEN 1 + WHEN prefix > 0 AND prefix < 128 AND (128 - prefix) <= 32 THEN CAST(POW(2, 128 - prefix) AS UNSIGNED) + ELSE 0 + END + ), 0) + FROM ( + SELECT + BIT_COUNT(mask1) + BIT_COUNT(mask2) + BIT_COUNT(mask3) + BIT_COUNT(mask4) AS prefix + FROM `' . $table . '` + ) networks + WHERE prefix >= 96 AND prefix <= 128'; + + return (int)$wpdb->get_var($sql); +} + +/** + * Counts IPv6 addresses covered by the firewall database. + */ +function spbc_security_firewall_update__get_ipv6_ips_count() +{ + return spbc_security_firewall_update__get_ipv6_ips_count_for_table(SPBC_TBL_FIREWALL_DATA_V6) + + spbc_security_firewall_update__get_ipv6_ips_count_for_table(SPBC_TBL_FIREWALL_DATA__IPS_V6); } function spbc_security_firewall_update__is_in_progress()