From 869731d729ab2e37ccbce11bcc26d4e433d966ef Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 Jan 2024 21:30:49 +0700 Subject: [PATCH 01/18] Fix. BTree. BTNode false --- cleantalk/lib/Cleantalk/ApbctUni/File/BTree.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cleantalk/lib/Cleantalk/ApbctUni/File/BTree.php b/cleantalk/lib/Cleantalk/ApbctUni/File/BTree.php index 65f0990..cafc75a 100755 --- a/cleantalk/lib/Cleantalk/ApbctUni/File/BTree.php +++ b/cleantalk/lib/Cleantalk/ApbctUni/File/BTree.php @@ -142,7 +142,7 @@ public function get( $key, $link = 0 ){ // No BTreeLeafNode was found if( $found === false ){ - // return false; + return false; } $leaf_links_to_search = array(); From 06f7c74555c25e0049903941e0ef5748c8b7a41c Mon Sep 17 00:00:00 2001 From: alexandergull Date: Thu, 29 Jun 2023 16:05:45 +0500 Subject: [PATCH 02/18] Fix. Exclusions. Laravel service routes added to url exclusions. --- cleantalk/inc/functions.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index 82cd99d..cd76ba8 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -60,14 +60,28 @@ function apbct_spam_test($data){ $exclusions_in_post = array(); } + $url_exclusions = array(); - // Skip check if + if ( + strpos($_SERVER['SCRIPT_NAME'], 'server.php') !== false //laravel sign + ) { + $url_exclusions = array( + 'recharge_user_by_wallet', + 'delete-user', + 'update-user', + 'password/email' + ); + } + + + + // Skip check if if ( $skip || // Skip flag set by apbct_get_fields_any() (!$sender_email && !$general_postdata_test) || // No email detected and general post data test is disabled ($registration && !$registrations_test) || // It's registration and registration check is disabled (apbct_check__exclusions()) || // main exclusion function (apbct_check__exclusions_in_post($exclusions_in_post)) || // Has an exclusions in POST - (apbct_check__url_exclusions()) // Has an exclusions in URL + (apbct_check__url_exclusions($url_exclusions)) // Has an exclusions in URL ) { $skip = true; } From 436deb32b6e98a71032158bb12b68932c51954e2 Mon Sep 17 00:00:00 2001 From: Glomberg Date: Tue, 28 May 2024 06:32:29 +0300 Subject: [PATCH 03/18] New. Integration. OpenMage integration and exclusions added. --- cleantalk/inc/admin.php | 4 ++++ cleantalk/inc/functions.php | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cleantalk/inc/admin.php b/cleantalk/inc/admin.php index bb09326..dbcceb8 100644 --- a/cleantalk/inc/admin.php +++ b/cleantalk/inc/admin.php @@ -265,6 +265,10 @@ function detect_cms( $path_to_index, $out = 'Unknown' ){ //moodle moodle if ( preg_match('/(moodle.*?)/', $index_file) ) { $out = 'moodle'; + } + // OpenMage + if ( preg_match('/(OpenMage.*?)/', $index_file) ) { + $out = 'OpenMage'; } } diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index cd76ba8..4c63c90 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -493,7 +493,12 @@ function apbct_check__url_exclusions( $exclusions = array() ){ $login_word = 'login/index.php'; break; } - //add a new rule if needs + case 'OpenMage': + { + $exclusions[] = 'sales_order_create'; + $exclusions[] = 'customer/validate'; + break; + } } } $exclusions[] = $login_word; From 72350e771114db4b5ef38517c0a31a9c1ad98e2d Mon Sep 17 00:00:00 2001 From: Glomberg Date: Tue, 25 Jun 2024 16:47:19 +0300 Subject: [PATCH 04/18] Fix. Spam protection. Request parsing fixed. --- cleantalk/cleantalk.php | 9 +++++++-- cleantalk/inc/functions.php | 13 +++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cleantalk/cleantalk.php b/cleantalk/cleantalk.php index b326446..498b556 100644 --- a/cleantalk/cleantalk.php +++ b/cleantalk/cleantalk.php @@ -117,9 +117,14 @@ function ct_attach_js($buffer){ apbct_spam_test($_GET); } + $request_data = $_POST; + if ( empty($request_data) ) { + $request_data = getRequestDataFromRaw(); + } + // General spam test - if(!empty($_POST)){ - apbct_spam_test($_POST); + if( ! empty($request_data) ){ + apbct_spam_test($request_data); } // Set Cookies test for cookie test diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index 4c63c90..498bd04 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -5,6 +5,19 @@ use Cleantalk\Variables\Cookie; use Cleantalk\Variables\Post; +function getRequestDataFromRaw() +{ + $raw = file_get_contents('php://input'); + if ( ! $raw ) { + return array(); + } + $json = json_decode($raw, true); + if ( ! $json ) { + return array(); + } + return $json; +} + /* * Performs spam test * @return void or exit script From cd1ab2353dc6c446507c6783069021155530f3ae Mon Sep 17 00:00:00 2001 From: Glomberg Date: Tue, 25 Jun 2024 16:47:33 +0300 Subject: [PATCH 05/18] Fix. Spam protection. JS including fixed. --- cleantalk/cleantalk.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cleantalk/cleantalk.php b/cleantalk/cleantalk.php index 498b556..740fdf1 100644 --- a/cleantalk/cleantalk.php +++ b/cleantalk/cleantalk.php @@ -66,7 +66,7 @@ function ct_attach_js($buffer){ global $apbct_checkjs_val; if( !(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') // No ajax - && preg_match('/^\s*(/i', $buffer) == 1 // Only for HTML documents + && preg_match('/\s*(/i', $buffer) == 1 // Only for HTML documents ){ $html_addition = '' From 0fd36c42b4f7d92298c310306ba67d829bc1b1bc Mon Sep 17 00:00:00 2001 From: alexandergull Date: Fri, 26 Jul 2024 14:52:27 +0500 Subject: [PATCH 06/18] New. Exclusions. Exclusion by sign in the form POST data implemented. --- cleantalk/config.php | 7 +- cleantalk/inc/admin.php | 135 ++++++++++++++++++++++++++++++++++-- cleantalk/inc/functions.php | 57 ++++++++++----- cleantalk/js/custom.js | 18 ++++- cleantalk/settings.php | 58 +++++++++++++--- 5 files changed, 239 insertions(+), 36 deletions(-) diff --git a/cleantalk/config.php b/cleantalk/config.php index cfcf59d..844cd49 100644 --- a/cleantalk/config.php +++ b/cleantalk/config.php @@ -5,7 +5,12 @@ $registrations_test = true; $general_postdata_test = false; $spam_firewall = true; - $general_post_exclusion_usage = false; + // exclusion by service field + $service_field_in_post_exclusion_enabled = false; + //form post data signs exclusions + $form_post_exclusions_enabled = false; + $form_post_signs_exclusions_set = array ( +); // Statistics $sfw_last_update = 0; diff --git a/cleantalk/inc/admin.php b/cleantalk/inc/admin.php index dbcceb8..503f89f 100644 --- a/cleantalk/inc/admin.php +++ b/cleantalk/inc/admin.php @@ -206,7 +206,7 @@ function uninstall( $files = array() ){ File::replace__variable( $path_to_config, 'registrations_test', true ); File::replace__variable( $path_to_config, 'general_postdata_test', false ); File::replace__variable( $path_to_config, 'spam_firewall', true ); - File::replace__variable( $path_to_config, 'general_post_exclusion_usage', false ); + File::replace__variable( $path_to_config, 'service_field_in_post_exclusion_enabled', false ); // Deleting cron tasks File::replace__variable( CLEANTALK_CRON_FILE, 'tasks', array() ); @@ -300,13 +300,13 @@ function apbct__plugin_update_message() { */ function apbct__cscart_js_snippet() { global $apikey, $apbct_salt, $detected_cms; - + // Only for CsCart if ($detected_cms != 'cscart') return; - + $apbct_checkjs_hash = apbct_checkjs_hash($apikey, $apbct_salt); ?> - +

Add this code to all pages of the site (use the basic template). Detailed instruction is here

@@ -320,3 +320,130 @@ function apbct__cscart_js_snippet() {
 
     %s
Learn more

+ + '; + $signs = ''; + foreach ( $form_post_signs_exclusions_set as $sign) { + if (is_string($sign)) { + $signs .= $sign . "\r\n"; + } + } + + $style_textarea = 'word-break: break-all; padding: 1%; background: #fff; width: 100%'; + $style_span = 'display: flex; justify-content: flex-end; margin: 1%'; + + return sprintf($template, $hint_text, $style_span, $link_learn_more, $style_textarea, htmlspecialchars($signs)); +} + +function apbct__prepare_service_field_exclusion_layout() +{ + global $exclusion_key; + + if (!empty($exclusion_key)) { + $service_field = htmlspecialchars(''); + } else { + $service_field = 'Error! Can not gain exclusion key.'; + } + + $hint_text = 'Regular expression. If the form contains any of these signs in POST array keys or in value of "action" key, the whole form submission is excluded from spam checking.'; + $style = 'border: solid 1px; word-break: break-all; padding: 1%; background: #fff;'; + + $template = ' +

%s

+
+ %s +
+ '; + + return $exclusion_key ? sprintf($template, $hint_text, $style, $service_field) : $service_field; +} +/** + * Sanitize and validate exclusions. + * Explode given string by commas and trim each string. + * Cut first 20 entities if more than 20 given. Remove duplicates. + * Skip element if it's empty. Validate entity as URL. Cut first 128 chars if more than 128 given + * + * Return false if exclusion is bad + * Return sanitized string if all is ok + * + * @param string $exclusions + * @param bool $regexp + * + * @return bool|string|array + */ +function apbct_settings__sanitize__exclusions($exclusions, $return_array = false, $regexp = true, $urls = false) +{ + if ( ! is_string($exclusions) ) { + return false; + } + + $result = array(); + $type = 0; + + if ( ! empty($exclusions) ) { + if ( strpos($exclusions, "\r\n") !== false ) { + $exclusions = explode("\r\n", $exclusions); + $type = 2; + } elseif ( strpos($exclusions, "\n") !== false ) { + $exclusions = explode("\n", $exclusions); + $type = 1; + } else { + $exclusions = explode(',', $exclusions); + } + //Drop duplicates first (before cut) + $exclusions = array_unique($exclusions); + //Take first 20 exclusions entities + $exclusions = array_slice($exclusions, 0, 20); + //Sanitizing + foreach ($exclusions as $exclusion) { + //Cut exclusion if more than 128 symbols gained + $sanitized_exclusion = substr($exclusion, 0, 128); + $sanitized_exclusion = trim($sanitized_exclusion); + + if ( ! empty($sanitized_exclusion) ) { + if ( $regexp ) { + if ( @preg_match('/' . $exclusion . '/', '') === false) { + return false; + } + } elseif ( $urls ) { + if ( + ( strpos($exclusion, 'http://') !== false || strpos($exclusion, 'https://') !== false ) && + filter_var($exclusion, FILTER_VALIDATE_URL) + ) { + return false; + } + } + $result[] = $sanitized_exclusion; + } + } + } + if ($return_array) { + return $result; + } + switch ( $type ) { + case 0: + default: + return implode(',', $result); + case 1: + return implode("\n", $result); + case 2: + return implode("\r\n", $result); + } +} diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index 498bd04..cb9ca24 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -29,8 +29,7 @@ function apbct_spam_test($data){ $registrations_test, $general_postdata_test, $detected_cms, - $exclusion_key, - $general_post_exclusion_usage; + $form_post_signs_exclusions_set; // Patch for old PHP versions. require_once( CLEANTALK_ROOT . 'lib' . DS . 'ct_phpFix.php'); @@ -64,15 +63,6 @@ function apbct_spam_test($data){ $registration = true; } - //init exclusions array if general_post_exclusion_usage is enabled - if ( isset($exclusion_key, $general_post_exclusion_usage) && $general_post_exclusion_usage ) { - $exclusions_in_post = array( - 'ct_service_data' => $exclusion_key, - ); - } else { - $exclusions_in_post = array(); - } - $url_exclusions = array(); if ( @@ -86,15 +76,13 @@ function apbct_spam_test($data){ ); } - - // Skip check if if ( $skip || // Skip flag set by apbct_get_fields_any() (!$sender_email && !$general_postdata_test) || // No email detected and general post data test is disabled ($registration && !$registrations_test) || // It's registration and registration check is disabled - (apbct_check__exclusions()) || // main exclusion function - (apbct_check__exclusions_in_post($exclusions_in_post)) || // Has an exclusions in POST - (apbct_check__url_exclusions($url_exclusions)) // Has an exclusions in URL + (apbct_check__exclusions_general()) || // main exclusion function + (apbct_check__url_exclusions($url_exclusions)) || // Has an exclusions in URL + (apbct_check__form_signs_exclusions($data, $form_post_signs_exclusions_set)) // Has an exclusions in POST fields ) { $skip = true; } @@ -525,10 +513,37 @@ function apbct_check__url_exclusions( $exclusions = array() ){ return false; } + /** + * Check POST array for the exclusion form signs. Listen for array keys or for value in case if key is "action". + * @param array $form_data The POST array or another filtered array of form data. + * @param array $exclusions + * @return bool True if exclusion found in the keys of array, false otherwise. + */ + function apbct_check__form_signs_exclusions($form_data, $exclusions) + { + if ( is_array($exclusions) && is_array($form_data) ) { + foreach ( $exclusions as $exclusion ) { + foreach ($form_data as $key => $value) { + $haystack = ($key === 'action' || $key === 'data') ? $value : $key; + if ( + $haystack === $exclusion || + (is_string($haystack) && stripos($haystack, $exclusion) !== false) || + (is_string($haystack) && preg_match('@' . $exclusion . '@', $haystack) === 1) + ) { + return true; + } + } + } + return false; + } + return false; + } + + /** * Another function for excluding validation based on any number of parameters */ - function apbct_check__exclusions() { + function apbct_check__exclusions_general() { global $detected_cms; @@ -573,6 +588,14 @@ function apbct_check__exclusions() { return true; } + //init exclusions array if service_field_in_post_exclusion is enabled + if ( isset($exclusion_key, $service_field_in_post_exclusion_enabled) && $service_field_in_post_exclusion_enabled ) { + $service_field_exclusion = array( + 'ct_service_data' => $exclusion_key, + ); + return apbct_check__exclusions_in_post($service_field_exclusion); + } + if (\Cleantalk\Variables\Get::equal('controller', 'ajax') && \Cleantalk\Variables\Get::equal('do', 'passwordStrength') ) { diff --git a/cleantalk/js/custom.js b/cleantalk/js/custom.js index 1d45c39..2ec6d59 100644 --- a/cleantalk/js/custom.js +++ b/cleantalk/js/custom.js @@ -101,14 +101,23 @@ jQuery(document).ready(function($) { }); //set the block with special tag in dependence of post_exclusion_usage statement - $('#general_post_exclusion_usage').on('click', function(event) { + $('#service_field_in_post_exclusion_enabled').on('click', function(event) { let state = 'none' - if ($('#general_post_exclusion_usage').prop('checked')){ + if ($('#service_field_in_post_exclusion_enabled').prop('checked')){ state = 'inherit' } $('#exclusions-div').css('display',state) }); + //show array of exclusions + $('#form_post_exclusions_signs_usage').on('click', function(event) { + let state = 'none' + if ($('#form_post_exclusions_signs_usage').prop('checked')){ + state = 'inherit' + } + $('#form_signs_exclusions-div').css('display',state) + }); + $('#btn-login').on('click', function(event) { login(); @@ -290,7 +299,10 @@ jQuery(document).ready(function($) { registrations_test: $('#check_reg').is(':checked') ? 1 : 0, general_postdata_test: $('#check_without_email').is(':checked') ? 1 : 0, spam_firewall: $('#enable_sfw').is(':checked') ? 1 : 0, - general_post_exclusion_usage: $('#general_post_exclusion_usage').is(':checked') ? 1 : 0, + service_field_in_post_exclusion_enabled: $('#service_field_in_post_exclusion_enabled').is(':checked') ? 1 : 0, + // form post signs exclusion + form_post_exclusions_enabled: $('#form_post_exclusions_signs_usage').is(':checked') ? 1 : 0, + form_post_exclusions_signs_string: $('textarea#form_signs_exclusions-textarea').val(), }, { callback: function(result, data, params, obj) { diff --git a/cleantalk/settings.php b/cleantalk/settings.php index c10c333..c6b6f0f 100644 --- a/cleantalk/settings.php +++ b/cleantalk/settings.php @@ -98,9 +98,26 @@ File::replace__variable( $path_to_config, 'registrations_test', (bool)Post::get( 'registrations_test' ) ); File::replace__variable( $path_to_config, 'general_postdata_test', (bool)Post::get( 'general_postdata_test' ) ); File::replace__variable( $path_to_config, 'spam_firewall', (bool)Post::get( 'spam_firewall' ) ); - File::replace__variable( $path_to_config, 'general_post_exclusion_usage', (bool)Post::get( 'general_post_exclusion_usage' ) ); + File::replace__variable( $path_to_config, 'service_field_in_post_exclusion_enabled', (bool)Post::get( 'service_field_in_post_exclusion_enabled' ) ); - // SFW actions + // form post sign exclusions + $form_post_exclusions_enabled = (bool)Post::get('form_post_exclusions_enabled'); + $form_post_signs_exclusions_string = Post::get('form_post_exclusions_signs_string'); + + if ($form_post_exclusions_enabled && $form_post_signs_exclusions_string) { + $form_post_signs_exclusions_set = apbct_settings__sanitize__exclusions($form_post_signs_exclusions_string, true); + if (!$form_post_signs_exclusions_set || !is_array($form_post_signs_exclusions_set)) { + die(Err::add('Exclusion regexp is not valid.')->get_last( 'as_json' )); + } + File::replace__variable( $path_to_config, 'form_post_signs_exclusions_set', $form_post_signs_exclusions_set ); + File::replace__variable( $path_to_config, 'form_post_exclusions_enabled', $form_post_exclusions_enabled ); + } else { + File::replace__variable( $path_to_config, 'form_post_exclusions_enabled', false ); + } + + /** + * SFW actions + */ if( Post::get( 'spam_firewall' ) && $apikey ){ $sfw = new SFW(); @@ -120,8 +137,9 @@ Err::check() or die(json_encode(array('success' => true))); die(Err::check_and_output( 'as_json' )); - }else + } else { die(Err::add('Forbidden')->get_last( 'as_json' )); + } break; case 'serve_run_cron_sfw_update': @@ -282,37 +300,55 @@ >

Account registered for email:

+
>
+
>
+
>
+
- > - + + > +
+ +
+
+ +
+ + > + +
-

Add the tag below to the form that needs to be excluded. Set unique "id" attribute if you have several forms on the same page:

-
- ') ?> -
+
+
>
+

Statistics


@@ -334,7 +370,7 @@
- +
From 192fa1bf78ed9357b2d0c9fde7604df07791ad43 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Fri, 26 Jul 2024 17:51:30 +0500 Subject: [PATCH 07/18] Upd. Exclusions. URL. Hardcoded URL for login page removed. --- cleantalk/inc/functions.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index cb9ca24..84c2736 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -485,13 +485,12 @@ function apbct_check__url_exclusions( $exclusions = array() ){ global $detected_cms; //custom login word transform ruleset - $login_word = 'login'; if ( isset($detected_cms) ) { switch ( $detected_cms ) { //moodle case case 'moodle': { - $login_word = 'login/index.php'; + $exclusions[] = 'login/index.php'; break; } case 'OpenMage': @@ -502,7 +501,6 @@ function apbct_check__url_exclusions( $exclusions = array() ){ } } } - $exclusions[] = $login_word; foreach ( $exclusions as $name => $exclusion ){ if( \Cleantalk\Variables\Server::has_string('REQUEST_URI', $exclusion ) ){ From 601fc079b6e89fb728b7d5fcc702423794999979 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Thu, 1 Aug 2024 18:01:32 +0500 Subject: [PATCH 08/18] Fix. File.php. Serialization issue fixed. --- cleantalk/config.php | 2 +- cleantalk/lib/Cleantalk/Common/File.php | 74 ++++++++++++++----------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/cleantalk/config.php b/cleantalk/config.php index 844cd49..8458ab9 100644 --- a/cleantalk/config.php +++ b/cleantalk/config.php @@ -1,5 +1,5 @@ Date: Mon, 5 Aug 2024 15:27:08 +0500 Subject: [PATCH 09/18] Fix. CleantalkRequest.php && BTreeLeaf.php. Creation dynamic properties fixed for 8.3. --- .../lib/Cleantalk/Antispam/Cleantalk.php | 10 ++- .../Cleantalk/Antispam/CleantalkRequest.php | 27 ++++--- .../lib/Cleantalk/ApbctUni/File/BTreeLeaf.php | 74 ++++++++++--------- 3 files changed, 59 insertions(+), 52 deletions(-) diff --git a/cleantalk/lib/Cleantalk/Antispam/Cleantalk.php b/cleantalk/lib/Cleantalk/Antispam/Cleantalk.php index 3d7eed0..fb289cd 100644 --- a/cleantalk/lib/Cleantalk/Antispam/Cleantalk.php +++ b/cleantalk/lib/Cleantalk/Antispam/Cleantalk.php @@ -100,7 +100,7 @@ class Cleantalk { /** * Function checks whether it is possible to publish the message * @param CleantalkRequest $request - * @return type + * @return CleantalkResponse */ public function isAllowMessage(CleantalkRequest $request) { $msg = $this->createMsg('check_message', $request); @@ -242,7 +242,7 @@ function_exists('base64_encode') /** * httpRequest * @param $msg - * @return boolean|CleantalkResponse + * @return CleantalkResponse */ private function httpRequest($msg) { @@ -375,8 +375,10 @@ public function get_servers_ip($host) /** * Send JSON request to servers - * @param $msg - * @return boolean|\CleantalkResponse + * @param $url + * @param $data + * @param $server_timeout + * @return boolean|CleantalkResponse */ private function sendRequest($url, $data, $server_timeout = 3) { diff --git a/cleantalk/lib/Cleantalk/Antispam/CleantalkRequest.php b/cleantalk/lib/Cleantalk/Antispam/CleantalkRequest.php index d364954..48de280 100644 --- a/cleantalk/lib/Cleantalk/Antispam/CleantalkRequest.php +++ b/cleantalk/lib/Cleantalk/Antispam/CleantalkRequest.php @@ -12,25 +12,25 @@ class CleantalkRequest { * @var string */ public $all_headers = null; - + /** * IP address of connection * @var string */ //public $remote_addr = null; - + /** * Last error number * @var integer */ public $last_error_no = null; - + /** * Last error time * @var integer */ public $last_error_time = null; - + /** * Last error text * @var string @@ -117,8 +117,11 @@ class CleantalkRequest { * @var int */ public $submit_time = null; - + public $x_forwarded_for = ''; + + public $x_forwarded_for_last = ''; + public $x_real_ip = ''; /** @@ -147,22 +150,22 @@ class CleantalkRequest { /** * Phone number - * @var type + * @var type */ public $phone = null; - + /** * Method name * @var string */ - public $method_name = 'check_message'; + public $method_name = 'check_message'; /** * Fill params with constructor * @param type $params */ public function __construct($params = null) { - + // IPs $this->sender_ip = isset($params['sender_ip']) ? (string)$params['sender_ip'] : null; $this->x_forwarded_for = isset($params['x_forwarded_for']) ? (string)$params['x_forwarded_for'] : null; @@ -178,14 +181,14 @@ public function __construct($params = null) { $this->submit_time = isset($params['submit_time']) ? (int)$params['submit_time'] : null; $this->post_info = isset($params['post_info']) ? (string)json_encode($params['post_info']) : null; $this->sender_info = isset($params['sender_info']) ? (string)json_encode($params['sender_info']) : null; - + // Message $this->message = !empty($params['message']) ? serialize($params['message']) : null; $this->example = !empty($params['example']) ? serialize($params['example']) : null; - + // Feedback $this->feedback = !empty($params['feedback']) ? $params['feedback'] : null; - + } } diff --git a/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php b/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php index 635a626..f32d319 100755 --- a/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php +++ b/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php @@ -3,7 +3,7 @@ namespace Cleantalk\ApbctUni\File; class BTreeLeaf { - + // Node structure private $max_elems_in_node; private $key_size; @@ -36,26 +36,28 @@ class BTreeLeaf { private $size; private $stream; - + + private $root_link; + public function __construct( $params, $link_or_elems ) { - + $this->stream = $params['stream']; foreach ( $params as $param_name => $value ) { $this->$param_name = $value; } - + if( is_array( $link_or_elems ) ){ $this->elements = $link_or_elems; }else{ - + $this->link = $link_or_elems === '' ? $this->link_size : $link_or_elems; // Set position to search fseek($this->stream, $this->link ); - + // Read node $raw_leaf = fread( $this->stream, $this->leaf_size ); @@ -65,7 +67,7 @@ public function __construct( $params, $link_or_elems ) { } public function insert( $key, $val, $link = '' ){ - + // Adding new element $this->elements[] = array( 'key' => $key, @@ -73,12 +75,12 @@ public function insert( $key, $val, $link = '' ){ 'link' => $link, ); $this->size++; - + // Sorting elements by key $keys = array_column( $this->elements, 'key' ); array_multisort( $keys, SORT_ASC, SORT_NUMERIC, $this->elements ); } - + /** * Searching for element in leaf using a key * @@ -106,59 +108,59 @@ public function searchForKey( $key_to_search ) // fwrite($myfile, json_encode($last_node)); // fwrite($myfile, PHP_EOL.PHP_EOL); // fclose($myfile); - + // Leaf is empty if( $this->isEmpty() ){ $out = false; - + // Leaf contains the exact key. Get all nodes with this key. }elseif( in_array( $key_to_search, array_column( $this->elements, 'key' ) ) ){ $out = $this->getNodesByKey( $key_to_search ); - + // No key found in this leaf. Get link to correct child // Check if it's on the right }elseif( $key_to_search > $last_node->key && $last_node->link_right ){ $last_node->link = $last_node->link_right; $out = array( $last_node ); - + // Check if it's on the left }elseif( $key_to_search < $first_node->key && $this->link_left ){ $first_node->link = $this->link_left; $out = array( $first_node ); - + // Get link from the middle }else{ - + // Binary search $top = $this->size - 1; $bot = 0; $position = 0; while( $top >= $bot ){ - + $position = (int) floor( ( $top + $bot ) / 2 ); - + if( $this->elements[ $position ]['key'] < $key_to_search ){ $bot = $position + 1; }elseif( $this->elements[ $position ]['key'] > $key_to_search ){ $top = $position - 1; } - + } - + $node = new BTreeLeafNode( $this->elements[ $position ] ); - + $node->link = $node->key < $key_to_search ? $node->link_right : $node->link_left; - + $out = array( $node ); } - + return isset( $out ) ? $out : false; } - + /** * Get all elements with such key from the node * @@ -167,18 +169,18 @@ public function searchForKey( $key_to_search ) * @return false|array of BTreeLeafNode */ private function getNodesByKey( $key ){ - + $out = array(); - + foreach( $this->elements as $array_key => $element ){ if( $element['key'] == $key ){ $out[] = new BTreeLeafNode( $element ); } } - + return $out ?: false; } - + public function split(){ return array( @@ -190,21 +192,21 @@ public function split(){ } private function unserialize( $leaf__raw ){ - + if( strlen( $leaf__raw ) < $this->leaf_size ) return null; - + // Get left link $this->link_left = str_replace( "\x00", '', substr( $leaf__raw, 0, $this->link_size ) ); - + // Get left link $this->link_parent = str_replace( "\x00", '', substr( $leaf__raw, $this->link_size, $this->link_size ) ); - + // Cut useless data $leaf__raw = substr( $leaf__raw, $this->link_size * 2, strpos( $leaf__raw, $this->eod ) - $this->link_size * 2 ); - + // Get data from raw and write it to $this->node $previous_link = $this->link_left; while ( $leaf__raw ) @@ -221,7 +223,7 @@ private function unserialize( $leaf__raw ){ } $this->size = $this->elements ? count( $this->elements ) : 0; - + } @@ -247,12 +249,12 @@ public function serialize( $raw = '' ){ return $raw; } - + public function save( $position = 0 ){ fseek( $this->stream, $this->link ); return fwrite( $this->stream, $this->serialize() ); } - + public function isEmpty(){ return ! $this->elements; } @@ -263,5 +265,5 @@ public function isEmpty(){ public function getSize() { return $this->size; } - + } From ba49d972b8e0cb24fe1f2fa1358395e9b5c9a674 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Mon, 5 Aug 2024 15:27:36 +0500 Subject: [PATCH 10/18] Fix. Helper. HTTP request. Get params preparing fixed. --- cleantalk/lib/Cleantalk/Common/Helper.php | 50 ++++++++++++++++------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/cleantalk/lib/Cleantalk/Common/Helper.php b/cleantalk/lib/Cleantalk/Common/Helper.php index 0b08980..c580388 100644 --- a/cleantalk/lib/Cleantalk/Common/Helper.php +++ b/cleantalk/lib/Cleantalk/Common/Helper.php @@ -541,11 +541,19 @@ static public function http__request($url, $data = array(), $presets = null, $op break; case 'get': - $opts[ CURLOPT_URL ] .= $data ? '?' . str_replace( "&", "&", http_build_query( $data ) ) : ''; - $opts[CURLOPT_POST] = false; - $opts[CURLOPT_POSTFIELDS] = null; + try { + $data = is_string($data) ? json_decode($data, true, 512, JSON_THROW_ON_ERROR) : $data; + } catch (\JsonException) { + $data = false; + } + if (is_array($data)) { + $opts[ CURLOPT_URL ] .= $data ? '?' . str_replace( "&", "&", http_build_query( $data ) ) : ''; + $opts[CURLOPT_POST] = false; + $opts[CURLOPT_POSTFIELDS] = null; + } else { + return array('error' => 'CURL. Preparing GET request: data param is not valid.'); + } break; - case 'ssl': $opts[CURLOPT_SSL_VERIFYPEER] = true; $opts[CURLOPT_SSL_VERIFYHOST] = 2; @@ -603,16 +611,30 @@ static public function http__request($url, $data = array(), $presets = null, $op $result = (int) preg_replace( '/.*(\d{3}).*/', '$1', $headers[0] ); // Making common request - }else{ - $opts = array( - 'http' => array( - 'method' => in_array( 'get', $presets ) ? 'GET' : 'POST', - 'timeout' => 5, - 'content' => str_replace( "&", "&", http_build_query( $data ) ), - ), - ); - $context = stream_context_create( $opts ); - $result = @file_get_contents( $url, 0, $context ); + } else { + $method = in_array( 'get', $presets ) ? 'GET' : 'POST'; + if ($method === 'GET') { + try { + $data = is_string($data) ? json_decode($data, true, 512, JSON_THROW_ON_ERROR) : $data; + $data = str_replace( "&", "&", http_build_query( $data ) ); + } catch (\JsonException) { + $data = false; + } + } + + if (is_string($data)) { + $opts = array( + 'http' => array( + 'method' => $method, + 'timeout' => 5, + 'content' => $data, + ), + ); + $context = stream_context_create( $opts ); + $result = @file_get_contents( $url, 0, $context ); + } else { + return array('error' => 'No CURL. Preparing GET request: data param is not valid.'); + } } $out = $result === false From 67441aed0192d6984b0ea9a18e1849f15c329b56 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Mon, 5 Aug 2024 17:06:51 +0500 Subject: [PATCH 11/18] Mod. Exclusions. Recursive array check if provided. --- cleantalk/inc/functions.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index 84c2736..5d77e68 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -522,6 +522,11 @@ function apbct_check__form_signs_exclusions($form_data, $exclusions) if ( is_array($exclusions) && is_array($form_data) ) { foreach ( $exclusions as $exclusion ) { foreach ($form_data as $key => $value) { + if ( !empty($value) && is_array($value) ) { + if ( apbct_check__form_signs_exclusions($value, $exclusions) ) { + return true; + } + } $haystack = ($key === 'action' || $key === 'data') ? $value : $key; if ( $haystack === $exclusion || From 326e952add5743148bb7627c4e6bb7f54ac853dc Mon Sep 17 00:00:00 2001 From: Glomberg Date: Thu, 8 Aug 2024 15:47:22 +0300 Subject: [PATCH 12/18] New. Integration. vBulletin CMS support implemented. --- cleantalk/inc/admin.php | 6 +++--- cleantalk/inc/functions.php | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cleantalk/inc/admin.php b/cleantalk/inc/admin.php index 503f89f..96e5ccd 100644 --- a/cleantalk/inc/admin.php +++ b/cleantalk/inc/admin.php @@ -266,9 +266,9 @@ function detect_cms( $path_to_index, $out = 'Unknown' ){ if ( preg_match('/(moodle.*?)/', $index_file) ) { $out = 'moodle'; } - // OpenMage - if ( preg_match('/(OpenMage.*?)/', $index_file) ) { - $out = 'OpenMage'; + // vBulletin + if ( preg_match('/(vBulletin.*?)/', $index_file) ) { + $out = 'vBulletin'; } } diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index 5d77e68..36fad46 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -412,6 +412,10 @@ function apbct_die($comment, $registration = false, $additional_text = null){ die(json_encode(array('status' =>'ok', 'text' => $comment))); } + if( $detected_cms === 'vBulletin' ) { + die(json_encode(['error' => $comment])); + } + // Custom ajax response require_once CLEANTALK_CONFIG_FILE; global $ajax_response; From 34f0f290c3f8b9407c2b4a8e56e13301805a82eb Mon Sep 17 00:00:00 2001 From: Glomberg Date: Thu, 8 Aug 2024 15:49:55 +0300 Subject: [PATCH 13/18] Fix. Code. `CleantalkResponse.php` - PHP 8+ fixed. --- cleantalk/lib/Cleantalk/Antispam/CleantalkResponse.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cleantalk/lib/Cleantalk/Antispam/CleantalkResponse.php b/cleantalk/lib/Cleantalk/Antispam/CleantalkResponse.php index 1a7b376..7035d2e 100644 --- a/cleantalk/lib/Cleantalk/Antispam/CleantalkResponse.php +++ b/cleantalk/lib/Cleantalk/Antispam/CleantalkResponse.php @@ -2,6 +2,8 @@ namespace Cleantalk\Antispam; +use Cleantalk\Common\Helper; + /** * Response class */ @@ -135,8 +137,8 @@ function __construct($response = null, $obj = null) { $this->errno = (isset($obj->errno)) ? $obj->errno : 0; $this->errstr = (isset($obj->errstr)) ? preg_replace("/.+(\*\*\*.+\*\*\*).+/", "$1", $obj->errstr) : null; - $this->stop_words = isset($obj->stop_words) ? utf8_decode($obj->stop_words) : null; - $this->comment = isset($obj->comment) ? utf8_decode($obj->comment) : null; + $this->stop_words = isset($obj->stop_words) ? Helper::fromUTF8($obj->stop_words) : null; + $this->comment = isset($obj->comment) ? Helper::fromUTF8($obj->comment) : null; $this->blacklisted = (isset($obj->blacklisted)) ? $obj->blacklisted : null; $this->allow = (isset($obj->allow)) ? $obj->allow : 1; $this->id = (isset($obj->id)) ? $obj->id : null; From edeb5dd3303a52f49b59861af73685b006185f06 Mon Sep 17 00:00:00 2001 From: Glomberg Date: Thu, 8 Aug 2024 15:50:27 +0300 Subject: [PATCH 14/18] Fix. Code. `BTreeLeaf.php` - PHP 8+ fixed. --- cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php | 1 + 1 file changed, 1 insertion(+) diff --git a/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php b/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php index f32d319..f655bd0 100755 --- a/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php +++ b/cleantalk/lib/Cleantalk/ApbctUni/File/BTreeLeaf.php @@ -2,6 +2,7 @@ namespace Cleantalk\ApbctUni\File; +#[\AllowDynamicProperties] class BTreeLeaf { // Node structure From 6d85bdaa5dd9dc683de1c88606db67bc58ad55f4 Mon Sep 17 00:00:00 2001 From: Glomberg Date: Thu, 8 Aug 2024 18:48:08 +0300 Subject: [PATCH 15/18] Revert "New. Integration. vBulletin CMS support implemented." This reverts commit 326e952add5743148bb7627c4e6bb7f54ac853dc. --- cleantalk/inc/admin.php | 6 +++--- cleantalk/inc/functions.php | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/cleantalk/inc/admin.php b/cleantalk/inc/admin.php index 96e5ccd..503f89f 100644 --- a/cleantalk/inc/admin.php +++ b/cleantalk/inc/admin.php @@ -266,9 +266,9 @@ function detect_cms( $path_to_index, $out = 'Unknown' ){ if ( preg_match('/(moodle.*?)/', $index_file) ) { $out = 'moodle'; } - // vBulletin - if ( preg_match('/(vBulletin.*?)/', $index_file) ) { - $out = 'vBulletin'; + // OpenMage + if ( preg_match('/(OpenMage.*?)/', $index_file) ) { + $out = 'OpenMage'; } } diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index 36fad46..5d77e68 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -412,10 +412,6 @@ function apbct_die($comment, $registration = false, $additional_text = null){ die(json_encode(array('status' =>'ok', 'text' => $comment))); } - if( $detected_cms === 'vBulletin' ) { - die(json_encode(['error' => $comment])); - } - // Custom ajax response require_once CLEANTALK_CONFIG_FILE; global $ajax_response; From 2077e7fbec30eb91a515d493b424bab8829c317e Mon Sep 17 00:00:00 2001 From: Glomberg Date: Thu, 8 Aug 2024 18:50:02 +0300 Subject: [PATCH 16/18] New. Integration. vBulletin CMS support implemented #2. --- cleantalk/inc/admin.php | 4 ++++ cleantalk/inc/functions.php | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/cleantalk/inc/admin.php b/cleantalk/inc/admin.php index 503f89f..1f28a37 100644 --- a/cleantalk/inc/admin.php +++ b/cleantalk/inc/admin.php @@ -270,6 +270,10 @@ function detect_cms( $path_to_index, $out = 'Unknown' ){ if ( preg_match('/(OpenMage.*?)/', $index_file) ) { $out = 'OpenMage'; } + // vBulletin + if ( preg_match('/(vBulletin.*?)/', $index_file) ) { + $out = 'vBulletin'; + } } return $out; diff --git a/cleantalk/inc/functions.php b/cleantalk/inc/functions.php index 5d77e68..b83a9df 100644 --- a/cleantalk/inc/functions.php +++ b/cleantalk/inc/functions.php @@ -412,6 +412,11 @@ function apbct_die($comment, $registration = false, $additional_text = null){ die(json_encode(array('status' =>'ok', 'text' => $comment))); } + // vBulletin integration + if( $detected_cms === 'vBulletin' ) { + die(json_encode(['error' => $comment])); + } + // Custom ajax response require_once CLEANTALK_CONFIG_FILE; global $ajax_response; From 845fb4bd32b2ab8e3d6d2759d4df6efd1c324b66 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Aug 2024 11:59:38 +0700 Subject: [PATCH 17/18] Update version 2.8.0 --- cleantalk/inc/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cleantalk/inc/common.php b/cleantalk/inc/common.php index 2fac069..24e7545 100644 --- a/cleantalk/inc/common.php +++ b/cleantalk/inc/common.php @@ -4,7 +4,7 @@ use Cleantalk\Variables\Server; define('APBCT_PLUGIN', 'uni'); -define('APBCT_VERSION', '2.7.2'); +define('APBCT_VERSION', '2.8.0'); define('APBCT_AGENT', APBCT_PLUGIN . '-' . str_replace( '.', '', APBCT_VERSION ) ); define('APBCT_USER_AGENT', 'Cleantalk-Antispam-Universal-Plugin/' . APBCT_VERSION); define('APBCT_INITIAL_INCLUDE_PATH', get_include_path()); From a64a5201bf43ef0d961fa645ca36676d8c6778d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Aug 2024 19:38:55 +0700 Subject: [PATCH 18/18] Fix. ConvertUTF8. Editing the regex pattern --- cleantalk/lib/Cleantalk/Common/Helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cleantalk/lib/Cleantalk/Common/Helper.php b/cleantalk/lib/Cleantalk/Common/Helper.php index c580388..81402b8 100644 --- a/cleantalk/lib/Cleantalk/Common/Helper.php +++ b/cleantalk/lib/Cleantalk/Common/Helper.php @@ -817,7 +817,7 @@ public static function fromUTF8($obj, $data_codepage = null) //String }else{ - if(preg_match('u', $obj) && function_exists('mb_convert_encoding') && $data_codepage !== null) + if(preg_match('/u/', $obj) && function_exists('mb_convert_encoding') && $data_codepage !== null) $obj = mb_convert_encoding($obj, $data_codepage, 'UTF-8'); } return $obj;