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 | /* class.phpmailer-bmh.php |
||
3 | .---------------------------------------------------------------------------. |
||
4 | | Software: PHPMailer-BMH (Bounce Mail Handler) | |
||
5 | | Version: 5.0.0rc1 | |
||
6 | | Contact: [email protected] | |
||
7 | | Info: http://phpmailer.codeworxtech.com | |
||
8 | | ------------------------------------------------------------------------- | |
||
9 | | Author: Andy Prevost [email protected] (admin) | |
||
10 | | Copyright (c) 2002-2009, Andy Prevost. All Rights Reserved. | |
||
11 | | ------------------------------------------------------------------------- | |
||
12 | | License: Distributed under the General Public License (GPL) | |
||
13 | | (http://www.gnu.org/licenses/gpl.html) | |
||
14 | | This program is distributed in the hope that it will be useful - WITHOUT | |
||
15 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
||
16 | | FITNESS FOR A PARTICULAR PURPOSE. | |
||
17 | | ------------------------------------------------------------------------- | |
||
18 | | This is a update of the original Bounce Mail Handler script | |
||
19 | | http://sourceforge.net/projects/bmh/ | |
||
20 | | The script has been renamed from Bounce Mail Handler to PHPMailer-BMH | |
||
21 | | ------------------------------------------------------------------------- | |
||
22 | | We offer a number of paid services: | |
||
23 | | - Web Hosting on highly optimized fast and secure servers | |
||
24 | | - Technology Consulting | |
||
25 | | - Oursourcing (highly qualified programmers and graphic designers) | |
||
26 | '---------------------------------------------------------------------------' |
||
27 | Last updated: January 21 2009 13:49 EST */ |
||
28 | |||
29 | /** |
||
30 | * PHPMailer-BMH (Bounce Mail Handler) |
||
31 | * |
||
32 | * PHPMailer-BMH is a PHP program to check your IMAP/POP3 inbox and |
||
33 | * delete all 'hard' bounced emails. It features a callback function where |
||
34 | * you can create a custom action. This provides you the ability to write |
||
35 | * a script to match your database records and either set inactive or |
||
36 | * delete records with email addresses that match the 'hard' bounce results. |
||
37 | * |
||
38 | * @package PHPMailer-BMH |
||
39 | * @author Andy Prevost |
||
40 | * @copyright 2008-2009, Andy Prevost |
||
41 | * @license GPL licensed |
||
42 | * @link http://sourceforge.net/projects/bmh |
||
43 | */ |
||
44 | require_once dirname(dirname(dirname(dirname(__DIR__)))) . '/mainfile.php'; |
||
45 | require_once XOOPS_ROOT_PATH . '/modules/xnewsletter/include/phpmailer_bmh/phpmailer-bmh_rules.php'; |
||
46 | |||
47 | define('VERBOSE_QUIET', 0); // means no output at all |
||
48 | define('VERBOSE_SIMPLE', 1); // means only output simple report |
||
49 | define('VERBOSE_REPORT', 2); // means output a detail report |
||
50 | define('VERBOSE_DEBUG', 3); // means output detail report as well as debug info. |
||
51 | |||
52 | /** |
||
53 | * Class BounceMailHandler |
||
54 | */ |
||
55 | class BounceMailHandler |
||
56 | { |
||
57 | ///////////////////////////////////////////////// |
||
58 | // PROPERTIES, PUBLIC |
||
59 | ///////////////////////////////////////////////// |
||
60 | |||
61 | /** |
||
62 | * Holds Bounce Mail Handler version. |
||
63 | * |
||
64 | * @var string |
||
65 | */ |
||
66 | public $Version = '5.0.0rc1 goffy'; |
||
67 | |||
68 | /** |
||
69 | * Holds result of last processing. |
||
70 | * |
||
71 | * @var array |
||
72 | */ |
||
73 | public $result_total = 0; |
||
74 | public $result_processed = 0; |
||
75 | public $result_unprocessed = 0; |
||
76 | public $result_deleted = 0; |
||
77 | public $result_moved = 0; |
||
78 | |||
79 | /** |
||
80 | * Mail server |
||
81 | * |
||
82 | * @var string |
||
83 | */ |
||
84 | public $mailhost = 'localhost'; |
||
85 | |||
86 | /** |
||
87 | * The username of mailbox |
||
88 | * |
||
89 | * @var string |
||
90 | */ |
||
91 | |||
92 | public $mailbox_username; |
||
93 | /** |
||
94 | * The password needed to access mailbox |
||
95 | * |
||
96 | * @var string |
||
97 | */ |
||
98 | public $mailbox_password; |
||
99 | |||
100 | /** |
||
101 | * The last error msg |
||
102 | * |
||
103 | * @var string |
||
104 | */ |
||
105 | public $error_msg; |
||
106 | |||
107 | /** |
||
108 | * Maximum limit messages processed in one batch |
||
109 | * |
||
110 | * @var int |
||
111 | */ |
||
112 | public $max_messages = 3000; |
||
113 | |||
114 | /** |
||
115 | * Callback Action function name |
||
116 | * the function that handles the bounce mail. Parameters: |
||
117 | * int $msgnum the message number returned by Bounce Mail Handler |
||
118 | * string $bounce_type the bounce type: 'antispam','autoreply','concurrent','content_reject','command_reject','internal_error','defer','delayed' => array('remove'=>0,'bounce_type'=>'temporary'),'dns_loop','dns_unknown','full','inactive','latin_only','other','oversize','outofoffice','unknown','unrecognized','user_reject','warning' |
||
119 | * string $email the target email address |
||
120 | * string $subject the subject, ignore now |
||
121 | * string $xheader the XBounceHeader from the mail |
||
122 | * 1 or 0 $remove delete status, 0 is not deleted, 1 is deleted |
||
123 | * string $rule_no bounce mail detect rule no. |
||
124 | * string $rule_cat bounce mail detect rule category |
||
125 | * int $totalFetched total number of messages in the mailbox |
||
126 | * |
||
127 | * @var string |
||
128 | */ |
||
129 | public $action_function = 'callbackAction'; |
||
130 | |||
131 | /** |
||
132 | * Internal variable |
||
133 | * The resource handler for the opened mailbox (POP3/IMAP/NNTP/etc.) |
||
134 | * |
||
135 | * @var object |
||
136 | */ |
||
137 | public $_mailbox_link = false; |
||
138 | |||
139 | /** |
||
140 | * Test mode, if true will not delete messages |
||
141 | * |
||
142 | * @var bool |
||
143 | */ |
||
144 | public $testmode = false; |
||
145 | |||
146 | /** |
||
147 | * Purge the unknown messages (or not) |
||
148 | * |
||
149 | * @var bool |
||
150 | */ |
||
151 | public $purge_unprocessed = false; |
||
152 | |||
153 | /** |
||
154 | * Control the debug output, default is VERBOSE_SIMPLE |
||
155 | * |
||
156 | * @var int |
||
157 | */ |
||
158 | public $verbose = VERBOSE_SIMPLE; |
||
159 | |||
160 | /** |
||
161 | * control the failed DSN rules output |
||
162 | * |
||
163 | * @var bool |
||
164 | */ |
||
165 | public $debug_dsn_rule = false; |
||
166 | |||
167 | /** |
||
168 | * control the failed BODY rules output |
||
169 | * |
||
170 | * @var bool |
||
171 | */ |
||
172 | public $debug_body_rule = false; |
||
173 | |||
174 | /** |
||
175 | * Control the method to process the mail header |
||
176 | * if set true, uses the imap_fetchstructure function |
||
177 | * otherwise, detect message type directly from headers, |
||
178 | * a bit faster than imap_fetchstructure function and take less resources. |
||
179 | * however - the difference is negligible |
||
180 | * |
||
181 | * @var bool |
||
182 | */ |
||
183 | public $use_fetchstructure = true; |
||
184 | |||
185 | /** |
||
186 | * If disable_delete is equal to true, it will disable the delete function |
||
187 | * |
||
188 | * @var bool |
||
189 | */ |
||
190 | public $disable_delete = false; |
||
191 | |||
192 | /* |
||
193 | * Defines new line ending |
||
194 | */ |
||
195 | public $bmh_newline = "<br>\n"; |
||
196 | |||
197 | /* |
||
198 | * Defines port number, default is '143', other common choices are '110' (pop3), '993' (gmail) |
||
199 | * @var integer |
||
200 | */ |
||
201 | public $port = 143; |
||
202 | |||
203 | /* |
||
204 | * Defines service, default is 'imap', choice includes 'pop3' |
||
205 | * @var string |
||
206 | */ |
||
207 | public $service = 'imap'; |
||
208 | |||
209 | /* |
||
210 | * Defines service option, default is 'notls', other choices are 'tls', 'ssl' |
||
211 | * @var string |
||
212 | */ |
||
213 | public $service_option = 'notls'; |
||
214 | |||
215 | /* |
||
216 | * Mailbox type, default is 'INBOX', other choices are (Tasks, Spam, Replies, etc.) |
||
217 | * @var string |
||
218 | */ |
||
219 | public $boxname = 'INBOX'; |
||
220 | |||
221 | /* |
||
222 | * Determines if soft bounces will be moved to another mailbox folder |
||
223 | * @var boolean |
||
224 | */ |
||
225 | public $moveSoft = false; |
||
226 | |||
227 | /* |
||
228 | * Mailbox folder to move soft bounces to, default is 'soft' |
||
229 | * @var string |
||
230 | */ |
||
231 | public $softMailbox = 'INBOX.soft'; |
||
232 | |||
233 | /* |
||
234 | * Determines if this mail should be moved to softMailbox |
||
235 | * @var boolean |
||
236 | */ |
||
237 | public $moveSoftFlag = false; |
||
238 | |||
239 | /* |
||
240 | * Determines if hard bounces will be moved to another mailbox folder |
||
241 | * NOTE: If true, this will disable delete and perform a move operation instead |
||
242 | * @var boolean |
||
243 | */ |
||
244 | public $moveHard = false; |
||
245 | |||
246 | /* |
||
247 | * Mailbox folder to move hard bounces to, default is 'hard' |
||
248 | * @var string |
||
249 | */ |
||
250 | public $hardMailbox = 'INBOX.hard'; |
||
251 | |||
252 | /* |
||
253 | * Determines if this mail should be moved to hardMailbox |
||
254 | * @var boolean |
||
255 | */ |
||
256 | public $moveHardFlag = false; |
||
257 | |||
258 | /* |
||
259 | * Deletes messages globally prior to date in variable |
||
260 | * NOTE: excludes any message folder that includes 'sent' in mailbox name |
||
261 | * format is same as MySQL: 'yyyy-mm-dd' |
||
262 | * if variable is blank, will not process global delete |
||
263 | * @var string |
||
264 | */ |
||
265 | public $deleteMsgDate = ''; |
||
266 | |||
267 | ///////////////////////////////////////////////// |
||
268 | // METHODS |
||
269 | ///////////////////////////////////////////////// |
||
270 | |||
271 | /** |
||
272 | * Output additional msg for debug |
||
273 | * |
||
274 | * @param bool|string $msg , if not given, output the last error msg |
||
275 | * @param int $verbose_level , the output level of this message |
||
276 | */ |
||
277 | public function output($msg = false, $verbose_level = VERBOSE_SIMPLE) |
||
278 | { |
||
279 | if ($this->verbose >= $verbose_level) { |
||
280 | if (empty($msg)) { |
||
281 | echo $this->error_msg . $this->bmh_newline; |
||
282 | } |
||
283 | //echo $msg . $this->bmh_newline; |
||
284 | } |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Open a mail box |
||
289 | * |
||
290 | * @return bool |
||
291 | */ |
||
292 | public function openMailbox() |
||
293 | { |
||
294 | // before starting the processing, let's check the delete flag and do global deletes if true |
||
295 | if ('' != trim($this->deleteMsgDate)) { |
||
296 | //echo "processing global delete based on date of " . $this->deleteMsgDate . "<br>"; |
||
297 | //$this->globalDelete($nameRaw); |
||
298 | $this->globalDelete(); |
||
299 | } |
||
300 | // disable move operations if server is Gmail ... Gmail does not support mailbox creation |
||
301 | // if ( stristr($this->mailhost,'gmail') ) { |
||
302 | // $this->moveSoft = false; |
||
303 | // $this->moveHard = false; |
||
304 | // } |
||
305 | $port = $this->port . '/' . $this->service . '/' . $this->service_option; |
||
306 | set_time_limit(6000); |
||
307 | //echo "{".$this->mailhost.":".$port."}" . $this->boxname."<br>"; |
||
308 | if (!$this->testmode) { |
||
309 | $this->_mailbox_link = imap_open('{' . $this->mailhost . ':' . $port . '}' . $this->boxname, $this->mailbox_username, $this->mailbox_password, CL_EXPUNGE); |
||
0 ignored issues
–
show
|
|||
310 | } else { |
||
311 | $this->_mailbox_link = imap_open('{' . $this->mailhost . ':' . $port . '}' . $this->boxname, $this->mailbox_username, $this->mailbox_password); |
||
0 ignored issues
–
show
It seems like
imap_open('{' . $this->m...this->mailbox_password) of type resource is incompatible with the declared type object of property $_mailbox_link .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
312 | } |
||
313 | if (!$this->_mailbox_link) { |
||
314 | $this->error_msg = 'Cannot create ' . $this->service . ' connection to ' . $this->mailhost . $this->bmh_newline . 'Error MSG: ' . imap_last_error(); |
||
315 | $this->output(); |
||
316 | |||
317 | return false; |
||
318 | } |
||
319 | $this->output('Connected to: ' . $this->mailhost . ' (' . $this->mailbox_username . ')'); |
||
320 | |||
321 | return true; |
||
322 | } |
||
323 | |||
324 | /** |
||
325 | * Open a mail box in local file system |
||
326 | * |
||
327 | * @param string $file_path (The local mailbox file path) |
||
328 | * |
||
329 | * @return bool |
||
330 | */ |
||
331 | public function openLocal($file_path) |
||
332 | { |
||
333 | set_time_limit(6000); |
||
334 | if (!$this->testmode) { |
||
335 | $this->_mailbox_link = imap_open((string)$file_path, '', '', CL_EXPUNGE); |
||
0 ignored issues
–
show
It seems like
imap_open((string) $file...th, '', '', CL_EXPUNGE) of type resource is incompatible with the declared type object of property $_mailbox_link .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
336 | } else { |
||
337 | $this->_mailbox_link = imap_open((string)$file_path, '', ''); |
||
0 ignored issues
–
show
It seems like
imap_open((string) $file_path, '', '') of type resource is incompatible with the declared type object of property $_mailbox_link .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
338 | } |
||
339 | if (!$this->_mailbox_link) { |
||
340 | $this->error_msg = 'Cannot open the mailbox file to ' . $file_path . $this->bmh_newline . 'Error MSG: ' . imap_last_error(); |
||
341 | $this->output(); |
||
342 | |||
343 | return false; |
||
344 | } |
||
345 | $this->output('Opened ' . $file_path); |
||
346 | |||
347 | return true; |
||
348 | } |
||
349 | |||
350 | /** |
||
351 | * Process the messages in a mailbox |
||
352 | * |
||
353 | * @param bool|string $max (maximum limit messages processed in one batch, if not given uses the property $max_messages |
||
354 | * |
||
355 | * @return bool |
||
356 | */ |
||
357 | public function processMailbox($max = false) |
||
358 | { |
||
359 | if (empty($this->action_function) || !function_exists($this->action_function)) { |
||
360 | $this->error_msg = 'Action function not found!'; |
||
361 | $this->output(); |
||
362 | |||
363 | return false; |
||
364 | } |
||
365 | |||
366 | if ($this->moveHard && (false === $this->disable_delete)) { |
||
367 | $this->disable_delete = true; |
||
368 | } |
||
369 | |||
370 | if (!empty($max)) { |
||
371 | $this->max_messages = $max; |
||
0 ignored issues
–
show
It seems like
$max of type boolean or string is incompatible with the declared type integer of property $max_messages .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
372 | } |
||
373 | |||
374 | // initialize counters |
||
375 | $c_total = imap_num_msg($this->_mailbox_link); |
||
376 | $c_fetched = $c_total; |
||
377 | $c_processed = 0; |
||
378 | $c_unprocessed = 0; |
||
379 | $c_deleted = 0; |
||
380 | $c_moved = 0; |
||
381 | $this->output('Total: ' . $c_total . ' messages '); |
||
382 | // proccess maximum number of messages |
||
383 | if ($c_fetched > $this->max_messages) { |
||
384 | $c_fetched = $this->max_messages; |
||
385 | $this->output('Processing first ' . $c_fetched . ' messages '); |
||
386 | } |
||
387 | |||
388 | if ($this->testmode) { |
||
389 | $this->output('Running in test mode, not deleting messages from mailbox<br>'); |
||
390 | } else { |
||
391 | if ($this->disable_delete) { |
||
392 | if ($this->moveHard) { |
||
393 | $this->output('Running in move mode<br>'); |
||
394 | } else { |
||
395 | $this->output('Running in disable_delete mode, not deleting messages from mailbox<br>'); |
||
396 | } |
||
397 | } else { |
||
398 | $this->output('Processed messages will be deleted from mailbox<br>'); |
||
399 | } |
||
400 | } |
||
401 | for ($x = 1; $x <= $c_fetched; ++$x) { |
||
402 | /* |
||
403 | $this->output( $x . ":",VERBOSE_REPORT); |
||
404 | if ($x % 10 == 0) { |
||
405 | $this->output( '.',VERBOSE_SIMPLE); |
||
406 | } |
||
407 | */ |
||
408 | // fetch the messages one at a time |
||
409 | if ($this->use_fetchstructure) { |
||
410 | $structure = imap_fetchstructure($this->_mailbox_link, $x); |
||
411 | if (1 == $structure->type |
||
412 | && $structure->ifsubtype |
||
413 | && 'REPORT' === $structure->subtype |
||
414 | && $structure->ifparameters |
||
415 | && $this->isParameter($structure->parameters, 'REPORT-TYPE', 'delivery-status')) { |
||
416 | $processed = $this->processBounce($x, 'DSN', $c_total); |
||
417 | View Code Duplication | } else { // not standard DSN msg |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
418 | $this->output('Msg #' . $x . ' is not a standard DSN message', VERBOSE_REPORT); |
||
419 | if ($this->debug_body_rule) { |
||
420 | $this->output(" Content-Type : {$match[1]}", VERBOSE_DEBUG); |
||
0 ignored issues
–
show
The variable
$match does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
421 | } |
||
422 | $processed = $this->processBounce($x, 'BODY', $c_total); |
||
423 | } |
||
424 | } else { |
||
425 | $header = imap_fetchheader($this->_mailbox_link, $x); |
||
426 | // Could be multi-line, if the new line begins with SPACE or HTAB |
||
427 | if (preg_match("/Content-Type:((?:[^\n]|\n[\t ])+)(?:\n[^\t ]|$)/is", $header, $match)) { |
||
428 | if (preg_match("/multipart\/report/is", $match[1]) |
||
429 | && preg_match("/report-type=[\"']?delivery-status[\"']?/is", $match[1])) { |
||
430 | // standard DSN msg |
||
431 | $processed = $this->processBounce($x, 'DSN', $c_total); |
||
432 | View Code Duplication | } else { // not standard DSN msg |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
433 | $this->output('Msg #' . $x . ' is not a standard DSN message', VERBOSE_REPORT); |
||
434 | if ($this->debug_body_rule) { |
||
435 | $this->output(" Content-Type : {$match[1]}", VERBOSE_DEBUG); |
||
436 | } |
||
437 | $processed = $this->processBounce($x, 'BODY', $c_total); |
||
438 | } |
||
439 | } else { // didn't get content-type header |
||
440 | $this->output('Msg #' . $x . ' is not a well-formatted MIME mail, missing Content-Type', VERBOSE_REPORT); |
||
441 | if ($this->debug_body_rule) { |
||
442 | $this->output(' Headers: ' . $this->bmh_newline . $header . $this->bmh_newline, VERBOSE_DEBUG); |
||
443 | } |
||
444 | $processed = $this->processBounce($x, 'BODY', $c_total); |
||
445 | } |
||
446 | } |
||
447 | |||
448 | $deleteFlag[$x] = false; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$deleteFlag was never initialized. Although not strictly required by PHP, it is generally a good practice to add $deleteFlag = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
449 | $moveFlag[$x] = false; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$moveFlag was never initialized. Although not strictly required by PHP, it is generally a good practice to add $moveFlag = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
450 | if ($processed) { |
||
451 | ++$c_processed; |
||
452 | if ((false === $this->testmode) && (false === $this->disable_delete)) { |
||
453 | // delete the bounce if not in test mode and not in disable_delete mode |
||
454 | @imap_delete($this->_mailbox_link, $x); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
455 | $deleteFlag[$x] = true; |
||
0 ignored issues
–
show
The variable
$deleteFlag does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
456 | ++$c_deleted; |
||
457 | } elseif ($this->moveHard && $this->moveHardFlag) { |
||
458 | // check if the move directory exists, if not create it |
||
459 | $this->mailbox_exist($this->hardMailbox); |
||
460 | // move the message |
||
461 | @imap_mail_move($this->_mailbox_link, $x, $this->hardMailbox); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
462 | $moveFlag[$x] = true; |
||
0 ignored issues
–
show
The variable
$moveFlag does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
463 | ++$c_moved; |
||
464 | } elseif ($this->moveSoft && $this->moveSoftFlag) { |
||
465 | // check if the move directory exists, if not create it |
||
466 | $this->mailbox_exist($this->softMailbox); |
||
467 | // move the message |
||
468 | @imap_mail_move($this->_mailbox_link, $x, $this->softMailbox); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
469 | $moveFlag[$x] = true; |
||
470 | ++$c_moved; |
||
471 | } |
||
472 | } else { // not processed |
||
473 | ++$c_unprocessed; |
||
474 | if (!$this->testmode && !$this->disable_delete && $this->purge_unprocessed) { |
||
475 | // delete this bounce if not in test mode, not in disable_delete mode, and the flag BOUNCE_PURGE_UNPROCESSED is set |
||
476 | @imap_delete($this->_mailbox_link, $x); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
477 | $deleteFlag[$x] = true; |
||
478 | ++$c_deleted; |
||
479 | } |
||
480 | } |
||
481 | flush(); |
||
482 | } |
||
483 | $this->output($this->bmh_newline . 'Closing mailbox, and purging messages'); |
||
484 | imap_close($this->_mailbox_link); |
||
485 | $this->output('Read: ' . $c_fetched . ' messages'); |
||
486 | $this->output($c_processed . ' action taken'); |
||
487 | $this->output($c_unprocessed . ' no action taken'); |
||
488 | $this->output($c_deleted . ' messages deleted'); |
||
489 | $this->output($c_moved . ' messages moved'); |
||
490 | |||
491 | $this->result_total = $c_fetched; |
||
0 ignored issues
–
show
It seems like
$c_fetched of type boolean or string or integer is incompatible with the declared type array of property $result_total .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
492 | $this->result_processed = $c_processed; |
||
493 | $this->result_unprocessed = $c_unprocessed; |
||
494 | $this->result_deleted = $c_deleted; |
||
495 | $this->result_moved = $c_moved; |
||
496 | |||
497 | return true; |
||
498 | } |
||
499 | |||
500 | /** |
||
501 | * Function to determine if a particular value is found in a imap_fetchstructure key |
||
502 | * |
||
503 | * @param array $currParameters (imap_fetstructure parameters) |
||
504 | * @param string $varKey (imap_fetstructure key) |
||
505 | * @param string $varValue (value to check for) |
||
506 | * |
||
507 | * @return bool |
||
508 | */ |
||
509 | public function isParameter($currParameters, $varKey, $varValue) |
||
510 | { |
||
511 | foreach ($currParameters as $key => $value) { |
||
512 | if ($key == $varKey) { |
||
513 | if ($value == $varValue) { |
||
514 | return true; |
||
515 | } |
||
516 | } |
||
517 | } |
||
518 | |||
519 | return false; |
||
520 | } |
||
521 | |||
522 | /** |
||
523 | * Function to process each individual message |
||
524 | * |
||
525 | * @param int $pos (message number) |
||
526 | * @param string $type (DNS or BODY type) |
||
527 | * @param string $totalFetched (total number of messages in mailbox) |
||
528 | * |
||
529 | * @return bool |
||
530 | */ |
||
531 | public function processBounce($pos, $type, $totalFetched) |
||
532 | { |
||
533 | $header = imap_headerinfo($this->_mailbox_link, $pos); |
||
534 | $subject = strip_tags($header->subject); |
||
535 | if ('DSN' === $type) { |
||
536 | // first part of DSN (Delivery Status Notification), human-readable explanation |
||
537 | $dsn_msg = imap_fetchbody($this->_mailbox_link, $pos, '1'); |
||
538 | $dsn_msg_structure = imap_bodystruct($this->_mailbox_link, $pos, '1'); |
||
539 | |||
540 | View Code Duplication | if (4 == $dsn_msg_structure->encoding) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
541 | $dsn_msg = quoted_printable_decode($dsn_msg); |
||
542 | } elseif (3 == $dsn_msg_structure->encoding) { |
||
543 | $dsn_msg = base64_decode($dsn_msg, true); |
||
544 | } |
||
545 | |||
546 | // second part of DSN (Delivery Status Notification), delivery-status |
||
547 | $dsn_report = imap_fetchbody($this->_mailbox_link, $pos, '2'); |
||
548 | |||
549 | // process bounces by rules |
||
550 | $result = bmhDSNRules($dsn_msg, $dsn_report, $this->debug_dsn_rule); |
||
551 | } elseif ('BODY' === $type) { |
||
552 | $structure = imap_fetchstructure($this->_mailbox_link, $pos); |
||
553 | switch ($structure->type) { |
||
554 | case 0: // Content-type = text |
||
555 | case 1: // Content-type = multipart |
||
556 | $body = imap_fetchbody($this->_mailbox_link, $pos, '1'); |
||
557 | // Detect encoding and decode - only base64 |
||
558 | if (4 == $structure->parts[0]->encoding) { |
||
559 | $body = quoted_printable_decode($body); |
||
560 | } elseif (3 == $structure->parts[0]->encoding) { |
||
561 | $body = base64_decode($body, true); |
||
562 | } |
||
563 | $result = bmhBodyRules($body, $structure, $this->debug_body_rule); |
||
0 ignored issues
–
show
$structure is of type object , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
564 | break; |
||
565 | case 2: // Content-type = message |
||
566 | $body = imap_body($this->_mailbox_link, $pos); |
||
567 | View Code Duplication | if (4 == $structure->encoding) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
568 | $body = quoted_printable_decode($body); |
||
569 | } elseif (3 == $structure->encoding) { |
||
570 | $body = base64_decode($body, true); |
||
571 | } |
||
572 | $body = mb_substr($body, 0, 1000); |
||
573 | $result = bmhBodyRules($body, $structure, $this->debug_body_rule); |
||
0 ignored issues
–
show
$structure is of type object , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
574 | break; |
||
575 | default: // unsupport Content-type |
||
576 | $this->output('Msg #' . $pos . ' is unsupported Content-Type:' . $structure->type, VERBOSE_REPORT); |
||
577 | |||
578 | return false; |
||
579 | } |
||
580 | } else { // internal error |
||
581 | $this->error_msg = 'Internal Error: unknown type'; |
||
582 | |||
583 | return false; |
||
584 | } |
||
585 | $email = $result['email']; |
||
586 | $bounce_type = $result['bounce_type']; |
||
587 | $this->moveHardFlag = false; |
||
588 | $this->moveSoftFlag = false; |
||
589 | if ($this->moveHard && 1 == $result['remove']) { |
||
590 | $remove = 'moved (hard)'; |
||
591 | $this->moveHardFlag = true; |
||
592 | } elseif ($this->moveSoft && 2 == $result['remove']) { |
||
593 | $remove = 'moved (soft)'; |
||
594 | $this->moveSoftFlag = true; |
||
595 | } elseif ($this->disable_delete) { |
||
596 | $remove = 0; |
||
597 | } else { |
||
598 | $remove = $result['remove']; |
||
599 | } |
||
600 | $rule_no = $result['rule_no']; |
||
601 | $rule_cat = $result['rule_cat']; |
||
602 | $xheader = false; |
||
603 | |||
604 | if ('0000' == $rule_no) { // internal error return false; |
||
605 | // code below will use the Callback function, but return no value |
||
606 | if ('' == trim($email)) { |
||
607 | $email = $header->fromaddress; |
||
608 | } |
||
609 | $params = [ |
||
610 | $pos, |
||
611 | $bounce_type, |
||
612 | $email, |
||
613 | $subject, |
||
614 | $xheader, |
||
615 | $remove, |
||
616 | $rule_no, |
||
617 | $rule_cat, |
||
618 | $totalFetched, |
||
619 | ]; |
||
620 | call_user_func_array($this->action_function, $params); |
||
621 | } else { // match rule, do bounce action |
||
622 | if ($this->testmode) { |
||
623 | $this->output('Match: ' . $rule_no . ':' . $rule_cat . '; ' . $bounce_type . '; ' . $email); |
||
624 | |||
625 | return true; |
||
626 | } |
||
627 | $params = [ |
||
628 | $pos, |
||
629 | $bounce_type, |
||
630 | $email, |
||
631 | $subject, |
||
632 | $xheader, |
||
633 | $remove, |
||
634 | $rule_no, |
||
635 | $rule_cat, |
||
636 | $totalFetched, |
||
637 | ]; |
||
638 | |||
639 | return call_user_func_array($this->action_function, $params); |
||
640 | } |
||
641 | |||
642 | return null; |
||
643 | } |
||
644 | |||
645 | /** |
||
646 | * Function to check if a mailbox exists |
||
647 | * - if not found, it will create it |
||
648 | * |
||
649 | * @param string $mailbox (the mailbox name, must be in 'INBOX.checkmailbox' format) |
||
650 | * @param bool $create (whether or not to create the checkmailbox if not found, defaults to true) |
||
651 | * |
||
652 | * @return null|bool |
||
653 | */ |
||
654 | public function mailbox_exist($mailbox, $create = true) |
||
655 | { |
||
656 | if ('' == trim($mailbox) || false === mb_strpos($mailbox, 'INBOX.')) { |
||
657 | // this is a critical error with either the mailbox name blank or an invalid mailbox name |
||
658 | // need to stop processing and exit at this point |
||
659 | echo "Invalid mailbox name for move operation. Cannot continue.<br>\n"; |
||
660 | echo "TIP: the mailbox you want to move the message to must include 'INBOX.' at the start.<br>\n"; |
||
661 | exit(); |
||
662 | } |
||
663 | $port = $this->port . '/' . $this->service . '/' . $this->service_option; |
||
664 | $mbox = imap_open('{' . $this->mailhost . ':' . $port . '}', $this->mailbox_username, $this->mailbox_password, OP_HALFOPEN); |
||
665 | $list = imap_getmailboxes($mbox, '{' . $this->mailhost . ':' . $port . '}', '*'); |
||
666 | $mailboxFound = false; |
||
667 | if (is_array($list)) { |
||
668 | foreach ($list as $key => $val) { |
||
669 | // get the mailbox name only |
||
670 | $nameArr = explode('}', imap_utf7_decode($val->name)); |
||
671 | $nameRaw = $nameArr[count($nameArr) - 1]; |
||
672 | if ($mailbox == $nameRaw) { |
||
673 | $mailboxFound = true; |
||
674 | } |
||
675 | } |
||
676 | if ((false === $mailboxFound) && $create) { |
||
677 | @imap_createmailbox($mbox, imap_utf7_encode('{' . $this->mailhost . ':' . $port . '}' . $mailbox)); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
678 | imap_close($mbox); |
||
679 | |||
680 | return true; |
||
681 | } |
||
682 | imap_close($mbox); |
||
683 | |||
684 | return false; |
||
685 | } |
||
686 | imap_close($mbox); |
||
687 | |||
688 | return false; |
||
689 | } |
||
690 | |||
691 | /** |
||
692 | * Function to delete messages in a mailbox, based on date |
||
693 | * NOTE: this is global ... will affect all mailboxes except any that have 'sent' in the mailbox name |
||
694 | * |
||
695 | * @internal param string $mailbox (the mailbox name) |
||
696 | */ |
||
697 | public function globalDelete() |
||
698 | { |
||
699 | $dateArr = explode('-', $this->deleteMsgDate); // date format is yyyy-mm-dd |
||
700 | $delDate = mktime(0, 0, 0, $dateArr[1], $dateArr[2], $dateArr[0]); |
||
701 | |||
702 | $port = $this->port . '/' . $this->service . '/' . $this->service_option; |
||
703 | $mboxt = imap_open('{' . $this->mailhost . ':' . $port . '}', $this->mailbox_username, $this->mailbox_password, OP_HALFOPEN); |
||
704 | $list = imap_getmailboxes($mboxt, '{' . $this->mailhost . ':' . $port . '}', '*'); |
||
705 | $mailboxFound = false; |
||
0 ignored issues
–
show
$mailboxFound is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
706 | if (is_array($list)) { |
||
707 | foreach ($list as $key => $val) { |
||
708 | // get the mailbox name only |
||
709 | $nameArr = explode('}', imap_utf7_decode($val->name)); |
||
710 | $nameRaw = $nameArr[count($nameArr) - 1]; |
||
711 | if (false === mb_stripos($nameRaw, 'sent')) { |
||
712 | $mboxd = imap_open('{' . $this->mailhost . ':' . $port . '}' . $nameRaw, $this->mailbox_username, $this->mailbox_password, CL_EXPUNGE); |
||
713 | $messages = imap_sort($mboxd, SORTDATE, 0); |
||
714 | $i = 0; |
||
715 | $check = imap_mailboxmsginfo($mboxd); |
||
0 ignored issues
–
show
$check is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
716 | foreach ($messages as $message) { |
||
717 | $header = imap_headerinfo($mboxd, $message); |
||
718 | $fdate = date('F j, Y', $header->udate); |
||
0 ignored issues
–
show
$fdate is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
719 | // purge if prior to global delete date |
||
720 | if ($header->udate < $delDate) { |
||
721 | imap_delete($mboxd, $message); |
||
722 | } |
||
723 | ++$i; |
||
724 | } |
||
725 | imap_expunge($mboxd); |
||
726 | imap_close($mboxd); |
||
727 | } |
||
728 | } |
||
729 | } |
||
730 | } |
||
731 | } |
||
732 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..