X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/5d244c8fd9a27c9f89dd08da2af6fbc67d4fce63..refs/tags/wordpress-4.4:/wp-content/plugins/akismet/class.akismet.php diff --git a/wp-content/plugins/akismet/class.akismet.php b/wp-content/plugins/akismet/class.akismet.php index 5c786526..ede1d1b9 100644 --- a/wp-content/plugins/akismet/class.akismet.php +++ b/wp-content/plugins/akismet/class.akismet.php @@ -9,7 +9,8 @@ class Akismet { private static $initiated = false; private static $prevent_moderation_email_for_these_comments = array(); private static $last_comment_result = null; - + private static $comment_as_submitted_allowed_keys = array( 'blog' => '', 'blog_charset' => '', 'blog_lang' => '', 'blog_ua' => '', 'comment_agent' => '', 'comment_author' => '', 'comment_author_IP' => '', 'comment_author_email' => '', 'comment_author_url' => '', 'comment_content' => '', 'comment_date_gmt' => '', 'comment_tags' => '', 'comment_type' => '', 'guid' => '', 'is_test' => '', 'permalink' => '', 'reporter' => '', 'site_domain' => '', 'submit_referer' => '', 'submit_uri' => '', 'user_ID' => '', 'user_agent' => '', 'user_id' => '', 'user_ip' => '' ); + public static function init() { if ( ! self::$initiated ) { self::init_hooks(); @@ -66,7 +67,14 @@ class Akismet { if ( $response[1] != 'valid' && $response[1] != 'invalid' ) return 'failed'; - self::update_alert( $response ); + return $response[1]; + } + + public static function deactivate_key( $key ) { + $response = self::http_post( Akismet::build_query( array( 'key' => $key, 'blog' => get_option('home') ) ), 'deactivate' ); + + if ( $response[1] != 'deactivated' ) + return 'failed'; return $response[1]; } @@ -124,9 +132,7 @@ class Akismet { do_action( 'akismet_comment_check_response', $response ); - self::update_alert( $response ); - - $commentdata['comment_as_submitted'] = array_intersect_key( $comment, array( 'blog' => '', 'blog_charset' => '', 'blog_lang' => '', 'blog_ua' => '', 'comment_agent' => '', 'comment_author' => '', 'comment_author_IP' => '', 'comment_author_email' => '', 'comment_author_url' => '', 'comment_content' => '', 'comment_date_gmt' => '', 'comment_tags' => '', 'comment_type' => '', 'guid' => '', 'is_test' => '', 'permalink' => '', 'reporter' => '', 'site_domain' => '', 'submit_referer' => '', 'submit_uri' => '', 'user_ID' => '', 'user_agent' => '', 'user_id' => '', 'user_ip' => '' ) ); + $commentdata['comment_as_submitted'] = array_intersect_key( $comment, self::$comment_as_submitted_allowed_keys ); $commentdata['akismet_result'] = $response[1]; if ( isset( $response[0]['x-akismet-pro-tip'] ) ) @@ -228,23 +234,32 @@ class Akismet { // normal result: true or false if ( self::$last_comment['akismet_result'] == 'true' ) { update_comment_meta( $comment->comment_ID, 'akismet_result', 'true' ); - self::update_comment_history( $comment->comment_ID, __('Akismet caught this comment as spam', 'akismet'), 'check-spam' ); + self::update_comment_history( $comment->comment_ID, '', 'check-spam' ); if ( $comment->comment_approved != 'spam' ) - self::update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s', 'akismet'), $comment->comment_approved), 'status-changed'.$comment->comment_approved ); + self::update_comment_history( + $comment->comment_ID, + '', + 'status-changed-'.$comment->comment_approved + ); } elseif ( self::$last_comment['akismet_result'] == 'false' ) { update_comment_meta( $comment->comment_ID, 'akismet_result', 'false' ); - self::update_comment_history( $comment->comment_ID, __('Akismet cleared this comment', 'akismet'), 'check-ham' ); + self::update_comment_history( $comment->comment_ID, '', 'check-ham' ); if ( $comment->comment_approved == 'spam' ) { if ( wp_blacklist_check($comment->comment_author, $comment->comment_author_email, $comment->comment_author_url, $comment->comment_content, $comment->comment_author_IP, $comment->comment_agent) ) - self::update_comment_history( $comment->comment_ID, __('Comment was caught by wp_blacklist_check', 'akismet'), 'wp-blacklisted' ); + self::update_comment_history( $comment->comment_ID, '', 'wp-blacklisted' ); else - self::update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s', 'akismet'), $comment->comment_approved), 'status-changed-'.$comment->comment_approved ); + self::update_comment_history( $comment->comment_ID, '', 'status-changed-'.$comment->comment_approved ); } } // abnormal result: error else { update_comment_meta( $comment->comment_ID, 'akismet_error', time() ); - self::update_comment_history( $comment->comment_ID, sprintf( __('Akismet was unable to check this comment (response: %s), will automatically retry again later.', 'akismet'), substr(self::$last_comment['akismet_result'], 0, 50)), 'check-error' ); + self::update_comment_history( + $comment->comment_ID, + '', + 'check-error', + array( 'response' => substr( self::$last_comment['akismet_result'], 0, 50 ) ) + ); } // record the complete original data as submitted for checking @@ -350,8 +365,15 @@ class Akismet { return $history; } - // log an event for a given comment, storing it in comment_meta - public static function update_comment_history( $comment_id, $message, $event=null ) { + /** + * Log an event for a given comment, storing it in comment_meta. + * + * @param int $comment_id The ID of the relevant comment. + * @param string $message The string description of the event. No longer used. + * @param string $event The event code. + * @param array $meta Metadata about the history entry. e.g., the user that reported or changed the status of a given comment. + */ + public static function update_comment_history( $comment_id, $message, $event=null, $meta=null ) { global $current_user; // failsafe for old WP versions @@ -359,15 +381,19 @@ class Akismet { return false; $user = ''; - if ( is_object( $current_user ) && isset( $current_user->user_login ) ) - $user = $current_user->user_login; $event = array( 'time' => self::_get_microtime(), - 'message' => $message, 'event' => $event, - 'user' => $user, ); + + if ( is_object( $current_user ) && isset( $current_user->user_login ) ) { + $event['user'] = $current_user->user_login; + } + + if ( ! empty( $meta ) ) { + $event['meta'] = $meta; + } // $unique = false so as to allow multiple values per comment $r = add_comment_meta( $comment_id, 'akismet_history', $event, false ); @@ -443,7 +469,7 @@ class Akismet { } } - self::update_comment_history( $comment->comment_ID, sprintf( __('%1$s changed the comment status to %2$s', 'akismet'), $reporter, $new_status ), 'status-' . $new_status ); + self::update_comment_history( $comment->comment_ID, '', 'status-' . $new_status ); } public static function submit_spam_comment( $comment_id ) { @@ -460,7 +486,7 @@ class Akismet { return; // use the original version stored in comment_meta if available - $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true); + $as_submitted = self::sanitize_comment_as_submitted( get_comment_meta( $comment_id, 'akismet_as_submitted', true ) ); if ( $as_submitted && is_array( $as_submitted ) && isset( $as_submitted['comment_content'] ) ) $comment = (object) array_merge( (array)$comment, $as_submitted ); @@ -488,7 +514,7 @@ class Akismet { $response = Akismet::http_post( Akismet::build_query( $comment ), 'submit-spam' ); if ( $comment->reporter ) { - self::update_comment_history( $comment_id, sprintf( __('%s reported this comment as spam', 'akismet'), $comment->reporter ), 'report-spam' ); + self::update_comment_history( $comment_id, '', 'report-spam' ); update_comment_meta( $comment_id, 'akismet_user_result', 'true' ); update_comment_meta( $comment_id, 'akismet_user', $comment->reporter ); } @@ -506,7 +532,7 @@ class Akismet { return; // use the original version stored in comment_meta if available - $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true); + $as_submitted = self::sanitize_comment_as_submitted( get_comment_meta( $comment_id, 'akismet_as_submitted', true ) ); if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) ) $comment = (object) array_merge( (array)$comment, $as_submitted ); @@ -534,7 +560,7 @@ class Akismet { $response = self::http_post( Akismet::build_query( $comment ), 'submit-ham' ); if ( $comment->reporter ) { - self::update_comment_history( $comment_id, sprintf( __('%s reported this comment as not spam', 'akismet'), $comment->reporter ), 'report-ham' ); + self::update_comment_history( $comment_id, '', 'report-ham' ); update_comment_meta( $comment_id, 'akismet_user_result', 'false' ); update_comment_meta( $comment_id, 'akismet_user', $comment->reporter ); } @@ -573,19 +599,19 @@ class Akismet { add_comment_meta( $comment_id, 'akismet_rechecking', true ); $status = self::check_db_comment( $comment_id, 'retry' ); - $msg = ''; + $event = ''; if ( $status == 'true' ) { - $msg = __( 'Akismet caught this comment as spam during an automatic retry.' , 'akismet'); + $event = 'cron-retry-spam'; } elseif ( $status == 'false' ) { - $msg = __( 'Akismet cleared this comment during an automatic retry.' , 'akismet'); + $event = 'cron-retry-ham'; } // If we got back a legit response then update the comment history // other wise just bail now and try again later. No point in // re-trying all the comments once we hit one failure. - if ( !empty( $msg ) ) { + if ( !empty( $event ) ) { delete_comment_meta( $comment_id, 'akismet_error' ); - self::update_comment_history( $comment_id, $msg, 'cron-retry' ); + self::update_comment_history( $comment_id, '', $event ); update_comment_meta( $comment_id, 'akismet_result', $status ); // make sure the comment status is still pending. if it isn't, that means the user has already moved it elsewhere. $comment = get_comment( $comment_id ); @@ -681,8 +707,21 @@ class Akismet { return ( isset( $comment1['comment_post_ID'], $comment2['comment_post_ID'] ) && intval( $comment1['comment_post_ID'] ) == intval( $comment2['comment_post_ID'] ) - && $comment1['comment_author'] == $comment2['comment_author'] - && $comment1['comment_author_email'] == $comment2['comment_author_email'] + && ( + // The comment author length max is 255 characters, limited by the TINYTEXT column type. + substr( $comment1['comment_author'], 0, 255 ) == substr( $comment2['comment_author'], 0, 255 ) + || substr( stripslashes( $comment1['comment_author'] ), 0, 255 ) == substr( $comment2['comment_author'], 0, 255 ) + || substr( $comment1['comment_author'], 0, 255 ) == substr( stripslashes( $comment2['comment_author'] ), 0, 255 ) + ) + && ( + // The email max length is 100 characters, limited by the VARCHAR(100) column type. + substr( $comment1['comment_author_email'], 0, 100 ) == substr( $comment2['comment_author_email'], 0, 100 ) + || substr( stripslashes( $comment1['comment_author_email'] ), 0, 100 ) == substr( $comment2['comment_author_email'], 0, 100 ) + || substr( $comment1['comment_author_email'], 0, 100 ) == substr( stripslashes( $comment2['comment_author_email'] ), 0, 100 ) + // Very long emails can be truncated and then stripped if the [0:100] substring isn't a valid address. + || ( ! $comment1['comment_author_email'] && strlen( $comment2['comment_author_email'] ) > 100 ) + || ( ! $comment2['comment_author_email'] && strlen( $comment1['comment_author_email'] ) > 100 ) + ) ); } @@ -882,8 +921,12 @@ class Akismet { do_action( 'akismet_https_disabled' ); } + + $simplified_response = array( $response['headers'], $response['body'] ); + + self::update_alert( $simplified_response ); - return array( $response['headers'], $response['body'] ); + return $simplified_response; } // given a response from an API call like check_key_status(), update the alert code options if an alert is present. @@ -999,7 +1042,7 @@ p { * @static */ public static function plugin_deactivation( ) { - //tidy up + return self::deactivate_key( self::get_api_key() ); } /** @@ -1085,4 +1128,26 @@ p { return $r; } + + /** + * Ensure that we are loading expected scalar values from akismet_as_submitted commentmeta. + * + * @param mixed $meta_value + * @return mixed + */ + private static function sanitize_comment_as_submitted( $meta_value ) { + if ( empty( $meta_value ) ) { + return $meta_value; + } + + $meta_value = (array) $meta_value; + + foreach ( $meta_value as $key => $value ) { + if ( ! isset( self::$comment_as_submitted_allowed_keys[$key] ) || ! is_scalar( $value ) ) { + unset( $meta_value[$key] ); + } + } + + return $meta_value; + } } \ No newline at end of file