@@ -111,13 +111,13 @@ public function setStream($stream) {
111
111
* @param $data String
112
112
*/
113
113
public function setText ($ data ) {
114
- // NOTE: This has been modified for Phabricator. If the input data does not
115
- // end in a newline, Mailparse fails to include the last line in the mail
116
- // body. This happens somewhere deep, deep inside the mailparse extension,
117
- // so adding a newline here seems like the most straightforward fix.
118
- if (!preg_match ('/\n\z/ ' , $ data )) {
119
- $ data = $ data ."\n" ;
120
- }
114
+ // NOTE: This has been modified for Phabricator. If the input data does not
115
+ // end in a newline, Mailparse fails to include the last line in the mail
116
+ // body. This happens somewhere deep, deep inside the mailparse extension,
117
+ // so adding a newline here seems like the most straightforward fix.
118
+ if (!preg_match ('/\n\z/ ' , $ data )) {
119
+ $ data = $ data ."\n" ;
120
+ }
121
121
122
122
$ this ->resource = mailparse_msg_create ();
123
123
// does not parse incrementally, fast memory hog might explode
@@ -203,23 +203,23 @@ public function getMessageBody($type = 'text') {
203
203
);
204
204
if (in_array ($ type , array_keys ($ mime_types ))) {
205
205
foreach ($ this ->parts as $ part ) {
206
- $ disposition = $ this ->getPartContentDisposition ($ part );
207
- if ($ disposition == 'attachment ' ) {
208
- // text/plain parts with "Content-Disposition: attachment" are
209
- // attachments, not part of the text body.
210
- continue ;
211
- }
206
+ $ disposition = $ this ->getPartContentDisposition ($ part );
207
+ if ($ disposition == 'attachment ' ) {
208
+ // text/plain parts with "Content-Disposition: attachment" are
209
+ // attachments, not part of the text body.
210
+ continue ;
211
+ }
212
212
if ($ this ->getPartContentType ($ part ) == $ mime_types [$ type ]) {
213
- $ headers = $ this ->getPartHeaders ($ part );
214
- // Concatenate all the matching parts into the body text. For example,
215
- // if a user sends a message with some text, then an image, and then
216
- // some more text, the text body of the email gets split over several
217
- // attachments.
213
+ $ headers = $ this ->getPartHeaders ($ part );
214
+ // Concatenate all the matching parts into the body text. For example,
215
+ // if a user sends a message with some text, then an image, and then
216
+ // some more text, the text body of the email gets split over several
217
+ // attachments.
218
218
$ body .= $ this ->decode (
219
219
$ this ->getPartBody ($ part ),
220
220
array_key_exists ('content-transfer-encoding ' , $ headers )
221
- ? $ headers ['content-transfer-encoding ' ]
222
- : '' );
221
+ ? $ headers ['content-transfer-encoding ' ]
222
+ : '' );
223
223
}
224
224
}
225
225
} else {
@@ -251,20 +251,42 @@ public function getMessageBodyHeaders($type = 'text') {
251
251
return $ headers ;
252
252
}
253
253
254
-
255
254
/**
256
255
* Returns the attachments contents in order of appearance
257
256
* @return Array
258
257
* @param $type Object[optional]
259
258
*/
260
259
public function getAttachments () {
260
+ // NOTE: This has been modified for Phabricator. Some mail clients do not
261
+ // send attachments with "Content-Disposition" headers.
261
262
$ attachments = array ();
262
263
$ dispositions = array ("attachment " ,"inline " );
263
- foreach ($ this ->parts as $ part ) {
264
+ $ non_attachment_types = array ("text/plain " , "text/html " );
265
+ $ nonameIter = 0 ;
266
+ foreach ($ this ->parts as $ part ) {
264
267
$ disposition = $ this ->getPartContentDisposition ($ part );
265
- if (in_array ($ disposition , $ dispositions )) {
268
+ $ filename = 'noname ' ;
269
+ if (isset ($ part ['disposition-filename ' ])) {
270
+ $ filename = $ part ['disposition-filename ' ];
271
+ } elseif (isset ($ part ['content-name ' ])) {
272
+ // if we have no disposition but we have a content-name, it's a valid attachment.
273
+ // we simulate the presence of an attachment disposition with a disposition filename
274
+ $ filename = $ part ['content-name ' ];
275
+ $ disposition = 'attachment ' ;
276
+ } elseif (!in_array ($ part ['content-type ' ], $ non_attachment_types , true )
277
+ && substr ($ part ['content-type ' ], 0 , 10 ) !== 'multipart/ '
278
+ ) {
279
+ // if we cannot get it with getMessageBody, we assume it is an attachment
280
+ $ disposition = 'attachment ' ;
281
+ }
282
+
283
+ if (in_array ($ disposition , $ dispositions ) && isset ($ filename ) === true ) {
284
+ if ($ filename == 'noname ' ) {
285
+ $ nonameIter ++;
286
+ $ filename = 'noname ' .$ nonameIter ;
287
+ }
266
288
$ attachments [] = new MimeMailParser_attachment (
267
- $ part [ ' disposition- filename' ] ,
289
+ $ filename ,
268
290
$ this ->getPartContentType ($ part ),
269
291
$ this ->getAttachmentStream ($ part ),
270
292
$ disposition ,
@@ -413,7 +435,7 @@ private function getPartBodyFromText(&$part) {
413
435
private function getAttachmentStream (&$ part ) {
414
436
$ temp_fp = tmpfile ();
415
437
416
- array_key_exists ('content-transfer-encoding ' , $ part ['headers ' ]) ? $ encoding = $ part ['headers ' ]['content-transfer-encoding ' ] : $ encoding = '' ;
438
+ array_key_exists ('content-transfer-encoding ' , $ part ['headers ' ]) ? $ encoding = $ part ['headers ' ]['content-transfer-encoding ' ] : $ encoding = '' ;
417
439
418
440
if ($ temp_fp ) {
419
441
if ($ this ->stream ) {
@@ -445,21 +467,21 @@ private function getAttachmentStream(&$part) {
445
467
}
446
468
447
469
448
- /**
449
- * Decode the string depending on encoding type.
450
- * @return String the decoded string.
451
- * @param $encodedString The string in its original encoded state.
452
- * @param $encodingType The encoding type from the Content-Transfer-Encoding header of the part.
453
- */
454
- private function decode ($ encodedString , $ encodingType ) {
455
- if (strtolower ($ encodingType ) == 'base64 ' ) {
456
- return base64_decode ($ encodedString );
457
- } else if (strtolower ($ encodingType ) == 'quoted-printable ' ) {
458
- return quoted_printable_decode ($ encodedString );
459
- } else {
460
- return $ encodedString ;
461
- }
462
- }
470
+ /**
471
+ * Decode the string depending on encoding type.
472
+ * @return String the decoded string.
473
+ * @param $encodedString The string in its original encoded state.
474
+ * @param $encodingType The encoding type from the Content-Transfer-Encoding header of the part.
475
+ */
476
+ private function decode ($ encodedString , $ encodingType ) {
477
+ if (strtolower ($ encodingType ) == 'base64 ' ) {
478
+ return base64_decode ($ encodedString );
479
+ } else if (strtolower ($ encodingType ) == 'quoted-printable ' ) {
480
+ return quoted_printable_decode ($ encodedString );
481
+ } else {
482
+ return $ encodedString ;
483
+ }
484
+ }
463
485
464
486
}
465
487
0 commit comments