Changeset - r11:0ea9b2bfb110
[Not reviewed]
v0.5 default
0 3 0
Wolfgang Scherer (ws) - 13 years ago 2012-03-30 21:10:05
wolfgang.scherer@gmx.de
lib/util.php: Quoted printable in headers is quite tricky.
Since vacation does not know how to handle mail header quoted printable,
avoid nested quoting by moving $SUBJECT outside of quoted parts.

lib/ws-vacation.conf.in: turn magic_quotes_gpc off (what a drag :))
3 files changed with 85 insertions and 23 deletions:
0 comments (0 inline, 0 general)
lib/util.php
Show inline comments
 
@@ -260,27 +260,86 @@ if (!function_exists("quoted_printable_e
 
         * this works, but replaces more characters than the minimum set. For readability
 
         * the spaces and CRLF pairs aren't encoded though.
 
         */
 
        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;
 
        }
 
    }
 
}
 

	
 
// there should be no need ... quoted_printable_decode is around since PHP4
 
if (!function_exists("quoted_printable_decode")) {
 
    if (function_exists("imap_qprint")) {
 
        echo "imap_qprint";
 
        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)
 
{
 
    $lines = explode("\n", $message);
 
    $subject = array_shift($lines);
 
@@ -293,55 +352,44 @@ function vacation_split($message, $decod
 
            break;
 
        }
 
        $headers[] = $line;
 
    }
 
    $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);
 
}
 

	
 
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);
 
}
 

	
 
//
 
// :ide-menu: Emacs IDE Menu - Buffer @BUFFER@
 
// . M-x `eIDE-menu' ()(eIDE-menu "z")
 
// :ide: COMPILE: PHP _DEBUG_=2 _DEBUG_TEST_=2
lib/ws-vacation.conf.in
Show inline comments
 
@@ -4,12 +4,13 @@ Alias /vacation @base_dir@
 
        Options FollowSymLinks Indexes
 
        AllowOverride All
 
        Order allow,deny
 
        Allow from all
 
        <IfModule mod_php5.c>
 
                AddType application/x-httpd-php .php
 
		php_flag magic_quotes_gpc Off
 
        </IfModule>
 
</Directory>
 

	
 
# :ide-menu: Emacs IDE Menu - Buffer @BUFFER@
 
# . M-x `eIDE-menu' ()(eIDE-menu "z")
 

	
test/qp-check.php
Show inline comments
 
@@ -19,15 +19,28 @@
 
// or write to Wolfgang Scherer, <Wolfgang.Scherer at gmx.de>
 

	
 
// $_REQUEST['_DEBUG_'] = 1;
 
// $_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];
 
$body = $vacationa[2];
 

	
 
$msg = vacation_join($subject, $body, $headers);
0 comments (0 inline, 0 general)