|
@@ -282,17 +282,52 @@ class Deliver {
|
|
|
global $username, $attachment_dir;
|
|
|
$hashed_attachment_dir = getHashedDir($username, $attachment_dir);
|
|
|
$filename = $message->att_local_name;
|
|
|
+
|
|
|
+ // inspect attached file for lines longer than allowed by RFC,
|
|
|
+ // in which case we'll be using base64 encoding (so we can split
|
|
|
+ // the lines up without corrupting them) instead of 8bit unencoded...
|
|
|
+ // (see RFC 2822/2.1.1)
|
|
|
+ //
|
|
|
+ // using 990 because someone somewhere is folding lines at
|
|
|
+ // 990 instead of 998 and I'm too lazy to find who it is
|
|
|
+ //
|
|
|
+ $file_has_long_lines = file_has_long_lines($hashed_attachment_dir
|
|
|
+ . '/' . $filename, 990);
|
|
|
+
|
|
|
$file = fopen ($hashed_attachment_dir . '/' . $filename, 'rb');
|
|
|
- while ($body_part = fgets($file, 4096)) {
|
|
|
- // remove NUL characters
|
|
|
- $body_part = str_replace("\0",'',$body_part);
|
|
|
- $length += $this->clean_crlf($body_part);
|
|
|
- if ($stream) {
|
|
|
- $this->preWriteToStream($body_part);
|
|
|
- $this->writeToStream($stream, $body_part);
|
|
|
+
|
|
|
+ // long lines were found, need to use base64 encoding
|
|
|
+ //
|
|
|
+ if ($file_has_long_lines) {
|
|
|
+ while ($tmp = fread($file, 570)) {
|
|
|
+ $body_part = chunk_split(base64_encode($tmp));
|
|
|
+ // Up to 4.3.10 chunk_split always appends a newline,
|
|
|
+ // while in 4.3.11 it doesn't if the string to split
|
|
|
+ // is shorter than the chunk length.
|
|
|
+ if( substr($body_part, -1 , 1 ) != "\n" )
|
|
|
+ $body_part .= "\n";
|
|
|
+ $length += $this->clean_crlf($body_part);
|
|
|
+ if ($stream) {
|
|
|
+ $this->writeToStream($stream, $body_part);
|
|
|
+ }
|
|
|
}
|
|
|
- $last = $body_part;
|
|
|
}
|
|
|
+
|
|
|
+ // no excessively long lines - normal 8bit
|
|
|
+ //
|
|
|
+ else {
|
|
|
+ while ($body_part = fgets($file, 4096)) {
|
|
|
+ // remove NUL characters
|
|
|
+ $body_part = str_replace("\0",'',$body_part);
|
|
|
+ $length += $this->clean_crlf($body_part);
|
|
|
+ if ($stream) {
|
|
|
+ $this->preWriteToStream($body_part);
|
|
|
+ $this->writeToStream($stream, $body_part);
|
|
|
+ }
|
|
|
+ $last = $body_part;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
fclose($file);
|
|
|
}
|
|
|
break;
|
|
@@ -461,10 +496,29 @@ class Deliver {
|
|
|
if ($mime_header->encoding) {
|
|
|
$header[] = 'Content-Transfer-Encoding: ' . $mime_header->encoding . $rn;
|
|
|
} else {
|
|
|
- if ($mime_header->type0 == 'text' || $mime_header->type0 == 'message') {
|
|
|
- $header[] = 'Content-Transfer-Encoding: 8bit' . $rn;
|
|
|
- } else if ($mime_header->type0 == 'multipart' || $mime_header->type0 == 'alternative') {
|
|
|
+
|
|
|
+ // inspect attached file for lines longer than allowed by RFC,
|
|
|
+ // in which case we'll be using base64 encoding (so we can split
|
|
|
+ // the lines up without corrupting them) instead of 8bit unencoded...
|
|
|
+ // (see RFC 2822/2.1.1)
|
|
|
+ //
|
|
|
+ if (!empty($message->att_local_name)) { // is this redundant? I have no idea
|
|
|
+ global $username, $attachment_dir;
|
|
|
+ $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
|
|
|
+ $filename = $hashed_attachment_dir . '/' . $message->att_local_name;
|
|
|
+
|
|
|
+ // using 990 because someone somewhere is folding lines at
|
|
|
+ // 990 instead of 998 and I'm too lazy to find who it is
|
|
|
+ //
|
|
|
+ $file_has_long_lines = file_has_long_lines($filename, 990);
|
|
|
+ } else
|
|
|
+ $file_has_long_lines = FALSE;
|
|
|
+
|
|
|
+ if ($mime_header->type0 == 'multipart' || $mime_header->type0 == 'alternative') {
|
|
|
/* no-op; no encoding needed */
|
|
|
+ } else if (($mime_header->type0 == 'text' || $mime_header->type0 == 'message')
|
|
|
+ && !$file_has_long_lines) {
|
|
|
+ $header[] = 'Content-Transfer-Encoding: 8bit' . $rn;
|
|
|
} else {
|
|
|
$header[] = 'Content-Transfer-Encoding: base64' . $rn;
|
|
|
}
|