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.