staylor /
WordPress
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Gets the email message from the user's mailbox to add as |
||
| 4 | * a WordPress post. Mailbox connection information must be |
||
| 5 | * configured under Settings > Writing |
||
| 6 | * |
||
| 7 | * @package WordPress |
||
| 8 | */ |
||
| 9 | |||
| 10 | /** Make sure that the WordPress bootstrap has run before continuing. */ |
||
| 11 | require(dirname(__FILE__) . '/wp-load.php'); |
||
| 12 | |||
| 13 | /** This filter is documented in wp-admin/options.php */ |
||
| 14 | if ( ! apply_filters( 'enable_post_by_email_configuration', true ) ) |
||
| 15 | wp_die( __( 'This action has been disabled by the administrator.' ) ); |
||
| 16 | |||
| 17 | /** |
||
| 18 | * Fires to allow a plugin to do a complete takeover of Post by Email. |
||
| 19 | * |
||
| 20 | * @since 2.9.0 |
||
| 21 | */ |
||
| 22 | do_action( 'wp-mail.php' ); |
||
| 23 | |||
| 24 | /** Get the POP3 class with which to access the mailbox. */ |
||
| 25 | require_once( ABSPATH . WPINC . '/class-pop3.php' ); |
||
| 26 | |||
| 27 | /** Only check at this interval for new messages. */ |
||
| 28 | if ( !defined('WP_MAIL_INTERVAL') ) |
||
| 29 | define('WP_MAIL_INTERVAL', 300); // 5 minutes |
||
| 30 | |||
| 31 | $last_checked = get_transient('mailserver_last_checked'); |
||
| 32 | |||
| 33 | if ( $last_checked ) |
||
| 34 | wp_die(__('Slow down cowboy, no need to check for new mails so often!')); |
||
| 35 | |||
| 36 | set_transient('mailserver_last_checked', true, WP_MAIL_INTERVAL); |
||
| 37 | |||
| 38 | $time_difference = get_option('gmt_offset') * HOUR_IN_SECONDS; |
||
| 39 | |||
| 40 | $phone_delim = '::'; |
||
| 41 | |||
| 42 | $pop3 = new POP3(); |
||
| 43 | |||
| 44 | if ( !$pop3->connect( get_option('mailserver_url'), get_option('mailserver_port') ) || !$pop3->user( get_option('mailserver_login') ) ) |
||
| 45 | wp_die( esc_html( $pop3->ERROR ) ); |
||
| 46 | |||
| 47 | $count = $pop3->pass( get_option('mailserver_pass') ); |
||
| 48 | |||
| 49 | if( false === $count ) |
||
| 50 | wp_die( esc_html( $pop3->ERROR ) ); |
||
| 51 | |||
| 52 | if( 0 === $count ) { |
||
| 53 | $pop3->quit(); |
||
| 54 | wp_die( __('There doesn’t seem to be any new mail.') ); |
||
| 55 | } |
||
| 56 | |||
| 57 | for ( $i = 1; $i <= $count; $i++ ) { |
||
| 58 | |||
| 59 | $message = $pop3->get($i); |
||
| 60 | |||
| 61 | $bodysignal = false; |
||
| 62 | $boundary = ''; |
||
| 63 | $charset = ''; |
||
| 64 | $content = ''; |
||
| 65 | $content_type = ''; |
||
| 66 | $content_transfer_encoding = ''; |
||
| 67 | $post_author = 1; |
||
| 68 | $author_found = false; |
||
| 69 | foreach ($message as $line) { |
||
| 70 | // Body signal. |
||
| 71 | if ( strlen($line) < 3 ) |
||
| 72 | $bodysignal = true; |
||
| 73 | if ( $bodysignal ) { |
||
| 74 | $content .= $line; |
||
| 75 | } else { |
||
| 76 | if ( preg_match('/Content-Type: /i', $line) ) { |
||
| 77 | $content_type = trim($line); |
||
| 78 | $content_type = substr($content_type, 14, strlen($content_type) - 14); |
||
| 79 | $content_type = explode(';', $content_type); |
||
| 80 | if ( ! empty( $content_type[1] ) ) { |
||
| 81 | $charset = explode('=', $content_type[1]); |
||
| 82 | $charset = ( ! empty( $charset[1] ) ) ? trim($charset[1]) : ''; |
||
| 83 | } |
||
| 84 | $content_type = $content_type[0]; |
||
| 85 | } |
||
| 86 | if ( preg_match('/Content-Transfer-Encoding: /i', $line) ) { |
||
| 87 | $content_transfer_encoding = trim($line); |
||
| 88 | $content_transfer_encoding = substr($content_transfer_encoding, 27, strlen($content_transfer_encoding) - 27); |
||
| 89 | $content_transfer_encoding = explode(';', $content_transfer_encoding); |
||
| 90 | $content_transfer_encoding = $content_transfer_encoding[0]; |
||
| 91 | } |
||
| 92 | if ( ( $content_type == 'multipart/alternative' ) && ( false !== strpos($line, 'boundary="') ) && ( '' == $boundary ) ) { |
||
| 93 | $boundary = trim($line); |
||
| 94 | $boundary = explode('"', $boundary); |
||
| 95 | $boundary = $boundary[1]; |
||
| 96 | } |
||
| 97 | if (preg_match('/Subject: /i', $line)) { |
||
| 98 | $subject = trim($line); |
||
| 99 | $subject = substr($subject, 9, strlen($subject) - 9); |
||
| 100 | // Captures any text in the subject before $phone_delim as the subject |
||
| 101 | if ( function_exists('iconv_mime_decode') ) { |
||
| 102 | $subject = iconv_mime_decode($subject, 2, get_option('blog_charset')); |
||
| 103 | } else { |
||
| 104 | $subject = wp_iso_descrambler($subject); |
||
| 105 | } |
||
| 106 | $subject = explode($phone_delim, $subject); |
||
| 107 | $subject = $subject[0]; |
||
| 108 | } |
||
| 109 | |||
| 110 | /* |
||
| 111 | * Set the author using the email address (From or Reply-To, the last used) |
||
| 112 | * otherwise use the site admin. |
||
| 113 | */ |
||
| 114 | if ( ! $author_found && preg_match( '/^(From|Reply-To): /', $line ) ) { |
||
| 115 | if ( preg_match('|[a-z0-9_.-]+@[a-z0-9_.-]+(?!.*<)|i', $line, $matches) ) |
||
| 116 | $author = $matches[0]; |
||
| 117 | else |
||
| 118 | $author = trim($line); |
||
| 119 | $author = sanitize_email($author); |
||
| 120 | if ( is_email($author) ) { |
||
| 121 | echo '<p>' . sprintf(__('Author is %s'), $author) . '</p>'; |
||
| 122 | $userdata = get_user_by('email', $author); |
||
| 123 | if ( ! empty( $userdata ) ) { |
||
| 124 | $post_author = $userdata->ID; |
||
| 125 | $author_found = true; |
||
| 126 | } |
||
| 127 | } |
||
| 128 | } |
||
| 129 | |||
| 130 | if ( preg_match( '/Date: /i', $line ) ) { // of the form '20 Mar 2002 20:32:37 +0100' |
||
| 131 | $ddate = str_replace( 'Date: ', '', trim( $line ) ); |
||
| 132 | $ddate = preg_replace( '!\s*\(.+\)\s*$!', '', $ddate ); // remove parenthesised timezone string if it exists, as this confuses strtotime |
||
| 133 | $ddate_U = strtotime( $ddate ); |
||
| 134 | $post_date = gmdate( 'Y-m-d H:i:s', $ddate_U + $time_difference ); |
||
| 135 | $post_date_gmt = gmdate( 'Y-m-d H:i:s', $ddate_U ); |
||
| 136 | } |
||
| 137 | } |
||
| 138 | } |
||
| 139 | |||
| 140 | // Set $post_status based on $author_found and on author's publish_posts capability |
||
| 141 | if ( $author_found ) { |
||
| 142 | $user = new WP_User($post_author); |
||
| 143 | $post_status = ( $user->has_cap('publish_posts') ) ? 'publish' : 'pending'; |
||
| 144 | } else { |
||
| 145 | // Author not found in DB, set status to pending. Author already set to admin. |
||
| 146 | $post_status = 'pending'; |
||
| 147 | } |
||
| 148 | |||
| 149 | $subject = trim($subject); |
||
| 150 | |||
| 151 | if ( $content_type == 'multipart/alternative' ) { |
||
| 152 | $content = explode('--'.$boundary, $content); |
||
| 153 | $content = $content[2]; |
||
| 154 | |||
| 155 | // Match case-insensitive content-transfer-encoding. |
||
| 156 | if ( preg_match( '/Content-Transfer-Encoding: quoted-printable/i', $content, $delim) ) { |
||
| 157 | $content = explode($delim[0], $content); |
||
| 158 | $content = $content[1]; |
||
| 159 | } |
||
| 160 | $content = strip_tags($content, '<img><p><br><i><b><u><em><strong><strike><font><span><div>'); |
||
| 161 | } |
||
| 162 | $content = trim($content); |
||
| 163 | |||
| 164 | /** |
||
| 165 | * Filters the original content of the email. |
||
| 166 | * |
||
| 167 | * Give Post-By-Email extending plugins full access to the content, either |
||
| 168 | * the raw content, or the content of the last quoted-printable section. |
||
| 169 | * |
||
| 170 | * @since 2.8.0 |
||
| 171 | * |
||
| 172 | * @param string $content The original email content. |
||
| 173 | */ |
||
| 174 | $content = apply_filters( 'wp_mail_original_content', $content ); |
||
| 175 | |||
| 176 | if ( false !== stripos($content_transfer_encoding, "quoted-printable") ) { |
||
| 177 | $content = quoted_printable_decode($content); |
||
| 178 | } |
||
| 179 | |||
| 180 | if ( function_exists('iconv') && ! empty( $charset ) ) { |
||
| 181 | $content = iconv($charset, get_option('blog_charset'), $content); |
||
| 182 | } |
||
| 183 | |||
| 184 | // Captures any text in the body after $phone_delim as the body |
||
| 185 | $content = explode($phone_delim, $content); |
||
| 186 | $content = empty( $content[1] ) ? $content[0] : $content[1]; |
||
| 187 | |||
| 188 | $content = trim($content); |
||
| 189 | |||
| 190 | /** |
||
| 191 | * Filters the content of the post submitted by email before saving. |
||
| 192 | * |
||
| 193 | * @since 1.2.0 |
||
| 194 | * |
||
| 195 | * @param string $content The email content. |
||
| 196 | */ |
||
| 197 | $post_content = apply_filters( 'phone_content', $content ); |
||
| 198 | |||
| 199 | $post_title = xmlrpc_getposttitle($content); |
||
| 200 | |||
| 201 | if ($post_title == '') $post_title = $subject; |
||
| 202 | |||
| 203 | $post_category = array(get_option('default_email_category')); |
||
| 204 | |||
| 205 | $post_data = compact('post_content','post_title','post_date','post_date_gmt','post_author','post_category', 'post_status'); |
||
| 206 | $post_data = wp_slash($post_data); |
||
| 207 | |||
| 208 | $post_ID = wp_insert_post($post_data); |
||
|
0 ignored issues
–
show
|
|||
| 209 | if ( is_wp_error( $post_ID ) ) |
||
| 210 | echo "\n" . $post_ID->get_error_message(); |
||
| 211 | |||
| 212 | // We couldn't post, for whatever reason. Better move forward to the next email. |
||
| 213 | if ( empty( $post_ID ) ) |
||
| 214 | continue; |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Fires after a post submitted by email is published. |
||
| 218 | * |
||
| 219 | * @since 1.2.0 |
||
| 220 | * |
||
| 221 | * @param int $post_ID The post ID. |
||
| 222 | */ |
||
| 223 | do_action( 'publish_phone', $post_ID ); |
||
| 224 | |||
| 225 | echo "\n<p><strong>" . __( 'Author:' ) . '</strong> ' . esc_html( $post_author ) . '</p>'; |
||
| 226 | echo "\n<p><strong>" . __( 'Posted title:' ) . '</strong> ' . esc_html( $post_title ) . '</p>'; |
||
| 227 | |||
| 228 | if(!$pop3->delete($i)) { |
||
| 229 | echo '<p>' . sprintf( |
||
| 230 | /* translators: %s: POP3 error */ |
||
| 231 | __( 'Oops: %s' ), |
||
| 232 | esc_html( $pop3->ERROR ) |
||
| 233 | ) . '</p>'; |
||
| 234 | $pop3->reset(); |
||
| 235 | exit; |
||
| 236 | } else { |
||
| 237 | echo '<p>' . sprintf( |
||
| 238 | /* translators: %s: the message ID */ |
||
| 239 | __( 'Mission complete. Message %s deleted.' ), |
||
| 240 | '<strong>' . $i . '</strong>' |
||
| 241 | ) . '</p>'; |
||
| 242 | } |
||
| 243 | |||
| 244 | } |
||
| 245 | |||
| 246 | $pop3->quit(); |
||
| 247 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.