diff --git a/lib/util.php b/lib/util.php --- a/lib/util.php +++ b/lib/util.php @@ -263,7 +263,6 @@ if (!function_exists("quoted_printable_e function quoted_printable_encode($string) { $string = str_replace(array('%20', '%0D%0A', '%'), array(' ', "\r\n", '='), rawurlencode($string)); $string = preg_replace('/[^\r\n]{73}[^=\r\n]{2}/', "$0=\r\n", $string); - $string = preg_replace('/=24SUBJECT/', '$SUBJECT', $string); return $string; } } @@ -276,8 +275,68 @@ if (!function_exists("quoted_printable_d function quoted_printable_decode($string) { return imap_qprint($string); } - } else { + } +} + +function subject_quoted_printable_encode ($subject) +{ + $parts = preg_split('/[$]SUBJECT/', $subject); + $indx = 0; + $partsq = Array(); + foreach ($parts as $part) { + if ( $indx > 0 ) { + $partsq[] = '$SUBJECT'; + } + $indx += 1; + if ( empty($part) ) { + continue; + } + $partq = quoted_printable_encode($part); + if ( $partq != $part ) { + $partq = preg_replace('/[?]/', '=3F', $partq); + $partsq[] = sprintf('=?utf-8?Q?%s?=', $partq); + } else { + $partsq[] = $partq; + } } + return implode($partsq, ''); +} + +function subject_quoted_printable_decode ($subject) +{ + $sdecoded = Array(); + $matches = Array(); + preg_match_all('/=[?]utf-8[?]Q[?]|[?]=/', $subject, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); + $indx = 0; + $limit = count($matches); + $start = 0; + for ( $indx = 0; $indx<$limit; ) { + $match = $matches[$indx][0][0]; + $offset = $matches[$indx][0][1]; + $indx += 1; + if ( $match != "=?utf-8?Q?") { + continue; + } + $sdecoded[] = substr($subject, $start, $offset - $start); + $start = $offset + strlen($match); + + if ( $indx>=$limit ) { + break; + } + + $match1 = $matches[$indx][0][0]; + $offset1 = $matches[$indx][0][1]; + $indx += 1; + if ( $match != "?=") { + // |:todo:| echo "warning: second match is not `?='\n";/* */ + } + + $epart = substr($subject, $start, $offset1 - $start); + $sdecoded[] = quoted_printable_decode($epart); + $start = $offset1 + strlen($match1); + } + $sdecoded[] = substr($subject, $start); + return implode($sdecoded, ''); } function vacation_split($message, $decode) @@ -296,14 +355,8 @@ function vacation_split($message, $decod } $headers = implode($headers, "\n"); $body = implode($lines, "\n"); - if ( $decode ) - { - if ( preg_match("/^=[?]/", $subject) ) - { - $subject = preg_replace('/^=[?]utf-8[?]Q[?]/', '', $subject); - $subject = preg_replace('/[?]=$/', '', $subject); - $subject = quoted_printable_decode($subject); - } + if ( $decode ) { + $subject = subject_quoted_printable_decode($subject); $body = quoted_printable_decode($body); } return Array($subject, $headers, $body); @@ -312,33 +365,28 @@ function vacation_split($message, $decod function vacation_join($subject, $body, $headers=Null) { $subject = trim($subject); - $subjectq = quoted_printable_encode($subject); - if ( $subjectq != $subject ) - { - $subject = sprintf('=?utf-8?Q?%s?=', $subjectq); - } + $subject = subject_quoted_printable_encode($subject); $subject = 'Subject: ' . $subject; $headera = Array( $subject, 'Content-Type: text/plain;'."\n" .' charset="utf-8"'."\n" .'Content-Transfer-Encoding: quoted-printable'); - if (!empty($headers)) - { + if (!empty($headers)) { $headers = trim($headers); - if (!empty($headers)) - { + if (!empty($headers)) { $headers = preg_replace("/\n\n+/", "\n", $headers); $headera[] = $headers; } } $headers = implode($headera, "\n"); - if (empty($body)) - { + if (empty($body)) { $body = ''; } + $body = quoted_printable_encode($body); + $body = preg_replace('/=24SUBJECT/', '$SUBJECT', $body); return sprintf("%s\n\n%s\n", - $headers, quoted_printable_encode($body)); + $headers, $body); } // diff --git a/lib/ws-vacation.conf.in b/lib/ws-vacation.conf.in --- a/lib/ws-vacation.conf.in +++ b/lib/ws-vacation.conf.in @@ -7,6 +7,7 @@ Alias /vacation @base_dir@ Allow from all AddType application/x-httpd-php .php + php_flag magic_quotes_gpc Off diff --git a/test/qp-check.php b/test/qp-check.php --- a/test/qp-check.php +++ b/test/qp-check.php @@ -22,9 +22,22 @@ // $_REQUEST['_DEBUG_TEST_'] = 1; require_once(dirname(__FILE__) . '/../lib/util.php'); -$msg = get_text('vacation'); echo "--------------------------------------------------\n"; +$subject = '$SUBJECT'; +$subject = 'Re: ?= $SUBJECT$SUBJECT, äöü ?=$SUBJECT'; +$subject = subject_quoted_printable_encode($subject); +echo 'Subject: ' . $subject . "\n"; +// var_dump($subject_partsq); + +echo "--------------------------------------------------\n"; + +$sencoded = $subject . '+' . $subject; +$subject = subject_quoted_printable_decode($sencoded); +echo 'Subject: ' . $subject . "\n"; + +echo "--------------------------------------------------\n"; +$msg = get_text('vacation'); $vacationa = vacation_split($msg, False); $subject = $vacationa[0]; $headers = $vacationa[1];