Changeset 45f56c1 in github


Ignore:
Timestamp:
May 29, 2008 12:10:42 PM (5 years ago)
Author:
thomascube <thomas@…>
Branches:
master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
Children:
681a59f
Parents:
06c1652d
Message:

Replace our crappy html sanitization with the dom-based washtml script + fix inline message parts + remove old code + add some doc comments

Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • installer/check.php

    r47124c22 r45f56c1  
    22<?php 
    33 
    4 $required_php_exts = array('PCRE' => 'pcre', 'Session' => 'session'); 
     4$required_php_exts = array('PCRE' => 'pcre', 'Session' => 'session', 'DOM XML' => 'dom'); 
    55 
    66$optional_php_exts = array('FileInfo' => 'fileinfo', 'Libiconv' => 'iconv', 
  • program/include/rcube_message.php

    r8fa58e7 r45f56c1  
    2222 
    2323/** 
    24  * Interface class for accessing an IMAP server 
    25  * 
    26  * This is a wrapper that implements the Iloha IMAP Library (IIL) 
     24 * Logical representation of a mail message with all its data 
     25 * and related functions 
    2726 * 
    2827 * @package    Mail 
     
    6665     
    6766    if ($this->structure = $this->imap->get_structure($uid)) { 
     67      $this->get_mime_numbers($this->structure); 
    6868      $this->parse_structure($this->structure); 
    69       $this->get_mime_numbers($this->structure); 
    7069    } 
    7170    else { 
     
    357356 
    358357      // if this was a related part try to resolve references 
    359       if ($message_ctype_secondary == 'related' && sizeof($this->inline_objects)) { 
     358      if ($message_ctype_secondary == 'related' && sizeof($this->inline_parts)) { 
    360359        $a_replaces = array(); 
    361360 
    362361        foreach ($this->inline_parts as $inline_object) { 
    363           $a_replaces['cid:'.$inline_object->content_id] = htmlspecialchars(sprintf($this->opt['get_url'], $inline_object->mime_id)); 
     362          $a_replaces['cid:'.$inline_object->content_id] = $this->get_part_url($inline_object->mime_id); 
    364363        } 
    365364 
    366365        // add replace array to each content part 
    367366        // (will be applied later when part body is available) 
    368         for ($i=0; $i<count($a_return_parts); $i++) { 
    369           if ($a_return_parts[$i]->type=='content') 
    370             $a_return_parts[$i]->replaces = $a_replaces; 
     367        foreach ($this->parts as $i => $part) { 
     368          if ($part->type == 'content') 
     369            $this->parts[$i]->replaces = $a_replaces; 
    371370        } 
    372371      } 
  • program/include/rcube_user.php

    r197601e r45f56c1  
    2525 * Class representing a system user 
    2626 * 
    27  * @package    core 
     27 * @package    Core 
    2828 * @author     Thomas Bruederli <roundcube@gmail.com> 
    2929 */ 
  • program/steps/mail/func.inc

    r2b962c10 r45f56c1  
    7575 
    7676 
    77 // return the message list as HTML table 
     77/** 
     78 * return the message list as HTML table 
     79 */ 
    7880function rcmail_message_list($attrib) 
    7981  { 
     
    296298 
    297299 
    298 // return javascript commands to add rows to the message list 
     300/** 
     301 * return javascript commands to add rows to the message list 
     302 */ 
    299303function rcmail_js_message_list($a_headers, $insert_top=FALSE) 
    300304  { 
     
    359363 
    360364 
    361 // return an HTML iframe for loading mail content 
     365/** 
     366 * return an HTML iframe for loading mail content 
     367 */ 
    362368function rcmail_messagecontent_frame($attrib) 
    363369  { 
     
    382388 
    383389 
     390/** 
     391 * 
     392 */ 
    384393function rcmail_messagecount_display($attrib) 
    385394  { 
     
    402411 
    403412 
     413/** 
     414 * 
     415 */ 
    404416function rcmail_quota_display($attrib) 
    405417  { 
     
    424436 
    425437 
     438/** 
     439 * 
     440 */ 
    426441function rcmail_quota_content($quota=NULL) 
    427442  { 
     
    467482 
    468483 
     484/** 
     485 * 
     486 */ 
    469487function rcmail_get_messagecount_text($count=NULL, $page=NULL) 
    470488  { 
     
    496514 
    497515 
    498 /* Stolen from Squirrelmail */ 
    499 function sq_deent(&$attvalue, $regex, $hex=false) 
    500   { 
    501   $ret_match = false; 
    502   preg_match_all($regex, $attvalue, $matches); 
    503   if (is_array($matches) && sizeof($matches[0]) > 0) 
    504     { 
    505     $repl = Array(); 
    506     for ($i = 0; $i < sizeof($matches[0]); $i++) 
    507       { 
    508       $numval = $matches[1][$i]; 
    509       if ($hex) 
    510         $numval = hexdec($numval); 
    511       $repl{$matches[0][$i]} = chr($numval); 
    512       } 
    513     $attvalue = strtr($attvalue, $repl); 
    514     return true; 
    515     } 
    516   else 
    517     return false; 
    518   } 
    519  
    520  
    521 /* Stolen verbatim from Squirrelmail */ 
    522 function sq_defang(&$attvalue) 
    523   { 
    524   /* Skip this if there aren't ampersands or backslashes. */ 
    525   if ((strpos($attvalue, '&') === false) && 
    526       (strpos($attvalue, '\\') === false)) 
    527     return; 
    528   $m = false; 
    529   do 
    530     { 
    531     $m = false; 
    532     $m = $m || sq_deent($attvalue, '/\&#0*(\d+);*/s'); 
    533     $m = $m || sq_deent($attvalue, '/\&#x0*((\d|[a-f])+);*/si', true); 
    534     $m = $m || sq_deent($attvalue, '/\\\\(\d+)/s', true); 
    535     } while ($m == true); 
    536   $attvalue = stripslashes($attvalue); 
    537   } 
    538  
    539  
    540 function rcmail_html_filter($html) 
    541   { 
    542   preg_match_all('/<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|\'.*?\'|[^\'">\s]+))?)+\s*|\s*)\/?>/', $html, $tags); 
    543  
    544   /* From Squirrelmail: Translate all dangerous Unicode or Shift_JIS characters which are accepted by 
    545    * IE as regular characters. */ 
    546   $replace = array(array('&#x029F;', '&#0671;',  /* L UNICODE IPA Extension */ 
    547                          '&#x0280;', '&#0640;',  /* R UNICODE IPA Extension */ 
    548                          '&#x0274;', '&#0628;',  /* N UNICODE IPA Extension */ 
    549                          '&#xFF25;', '&#65317;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER E */ 
    550                          '&#xFF45;', '&#65349;', /* Unicode FULLWIDTH LATIN SMALL LETTER E */ 
    551                          '&#xFF38;', '&#65336;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER X */ 
    552                          '&#xFF58;', '&#65368;', /* Unicode FULLWIDTH LATIN SMALL LETTER X */ 
    553                          '&#xFF30;', '&#65328;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER P */ 
    554                          '&#xFF50;', '&#65360;', /* Unicode FULLWIDTH LATIN SMALL LETTER P */ 
    555                          '&#xFF32;', '&#65330;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER R */ 
    556                          '&#xFF52;', '&#65362;', /* Unicode FULLWIDTH LATIN SMALL LETTER R */ 
    557                          '&#xFF33;', '&#65331;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER S */ 
    558                          '&#xFF53;', '&#65363;', /* Unicode FULLWIDTH LATIN SMALL LETTER S */ 
    559                          '&#xFF29;', '&#65321;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER I */ 
    560                          '&#xFF49;', '&#65353;', /* Unicode FULLWIDTH LATIN SMALL LETTER I */ 
    561                          '&#xFF2F;', '&#65327;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER O */ 
    562                          '&#xFF4F;', '&#65359;', /* Unicode FULLWIDTH LATIN SMALL LETTER O */ 
    563                          '&#xFF2E;', '&#65326;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER N */ 
    564                          '&#xFF4E;', '&#65358;', /* Unicode FULLWIDTH LATIN SMALL LETTER N */ 
    565                          '&#xFF2C;', '&#65324;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER L */ 
    566                          '&#xFF4C;', '&#65356;', /* Unicode FULLWIDTH LATIN SMALL LETTER L */ 
    567                          '&#xFF35;', '&#65333;', /* Unicode FULLWIDTH LATIN CAPITAL LETTER U */ 
    568                          '&#xFF55;', '&#65365;', /* Unicode FULLWIDTH LATIN SMALL LETTER U */ 
    569                          '&#x207F;', '&#8319;' , /* Unicode SUPERSCRIPT LATIN SMALL LETTER N */ 
    570                          "\xEF\xBC\xA5", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER E */ 
    571                                          /* in unicode this is some Chinese char range */ 
    572                          "\xEF\xBD\x85", /* Shift JIS FULLWIDTH LATIN SMALL LETTER E */ 
    573                          "\xEF\xBC\xB8", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER X */ 
    574                          "\xEF\xBD\x98", /* Shift JIS FULLWIDTH LATIN SMALL LETTER X */ 
    575                          "\xEF\xBC\xB0", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER P */ 
    576                          "\xEF\xBD\x90", /* Shift JIS FULLWIDTH LATIN SMALL LETTER P */ 
    577                          "\xEF\xBC\xB2", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER R */ 
    578                          "\xEF\xBD\x92", /* Shift JIS FULLWIDTH LATIN SMALL LETTER R */ 
    579                          "\xEF\xBC\xB3", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER S */ 
    580                          "\xEF\xBD\x93", /* Shift JIS FULLWIDTH LATIN SMALL LETTER S */ 
    581                          "\xEF\xBC\xA9", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER I */ 
    582                          "\xEF\xBD\x89", /* Shift JIS FULLWIDTH LATIN SMALL LETTER I */ 
    583                          "\xEF\xBC\xAF", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER O */ 
    584                          "\xEF\xBD\x8F", /* Shift JIS FULLWIDTH LATIN SMALL LETTER O */ 
    585                          "\xEF\xBC\xAE", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER N */ 
    586                          "\xEF\xBD\x8E", /* Shift JIS FULLWIDTH LATIN SMALL LETTER N */ 
    587                          "\xEF\xBC\xAC", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER L */ 
    588                          "\xEF\xBD\x8C", /* Shift JIS FULLWIDTH LATIN SMALL LETTER L */ 
    589                          "\xEF\xBC\xB5", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER U */ 
    590                          "\xEF\xBD\x95", /* Shift JIS FULLWIDTH LATIN SMALL LETTER U */ 
    591                          "\xE2\x81\xBF", /* Shift JIS FULLWIDTH SUPERSCRIPT N */ 
    592                          "\xCA\x9F",   /* L UNICODE IPA Extension */ 
    593                          "\xCA\x80",   /* R UNICODE IPA Extension */ 
    594                          "\xC9\xB4"),  /* N UNICODE IPA Extension */ 
    595                    array('l', 'l', 'r', 'r', 'n', 'n', 'E', 'E', 'e', 'e', 'X', 'X', 'x', 'x', 
    596                          'P', 'P', 'p', 'p', 'R', 'R', 'r', 'r', 'S', 'S', 's', 's', 'I', 'I', 
    597                          'i', 'i', 'O', 'O', 'o', 'o', 'N', 'N', 'n', 'n', 'L', 'L', 'l', 'l', 
    598                          'U', 'U', 'u', 'u', 'n', 'n', 'E', 'e', 'X', 'x', 'P', 'p', 'R', 'r', 
    599                          'S', 's', 'I', 'i', 'O', 'o', 'N', 'n', 'L', 'l', 'U', 'u', 'n', 'l', 'r', 'n')); 
    600   if ((count($tags)>3) && (count($tags[3])>0)) 
    601     foreach ($tags[3] as $nr=>$value) 
    602       { 
    603       /* Remove comments */ 
    604       $newvalue = preg_replace('/(\/\*.*\*\/)/','$2',$value); 
    605       /* Translate dangerous characters */ 
    606       $newvalue = str_replace($replace[0], $replace[1], $newvalue); 
    607       sq_defang($newvalue); 
    608       /* Rename dangerous CSS */ 
    609       $newvalue = preg_replace('/expression/i', 'idiocy', $newvalue); 
    610       $newvalue = preg_replace('/url/i', 'idiocy', $newvalue); 
    611       $newattrs = preg_replace('/'.preg_quote($value, '/').'$/', $newvalue, $tags[1][$nr]); 
    612       $newtag = preg_replace('/'.preg_quote($tags[1][$nr], '/').'/', $newattrs, $tags[0][$nr]); 
    613       $html = preg_replace('/'.preg_quote($tags[0][$nr], '/').'/', $newtag, $html); 
    614       } 
    615   return $html; 
    616   } 
    617  
    618  
     516/** 
     517 * 
     518 */ 
    619519function rcmail_print_body($part, $safe=FALSE, $plain=FALSE) 
    620   { 
    621   global $IMAP, $REMOTE_OBJECTS; 
    622    
    623   $body = is_array($part->replaces) ? strtr($part->body, $part->replaces) : $part->body; 
    624  
     520{ 
     521  global $REMOTE_OBJECTS; 
     522   
    625523  // convert html to text/plain 
    626   if ($part->ctype_secondary=='html' && $plain) 
    627     { 
    628     $txt = new html2text($body, false, true); 
     524  if ($part->ctype_secondary == 'html' && $plain) { 
     525    $txt = new html2text($part->body, false, true); 
    629526    $body = $txt->get_text(); 
    630527    $part->ctype_secondary = 'plain'; 
    631     } 
    632      
     528  } 
    633529  // text/html 
    634   if ($part->ctype_secondary=='html') 
    635     { 
    636     // remove charset specification in HTML message 
    637     $body = preg_replace('/charset=[a-z0-9\-]+/i', '', $body); 
    638  
    639     if (!$safe)  // remove remote images and scripts 
    640       { 
    641       $remote_patterns = array('/<img\s+(.*)src=(["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)(\2|\s|>)/Ui', 
    642                                '/(src|background)=(["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)(\2|\s|>)/Ui', 
    643                                '/(<base.*href=["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)([^<]*>)/i', 
    644                                '/(<link.*href=["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)([^<]*>)/i', 
    645                                '/url\s*\(["\']?([hftps]{3,5}:\/{2}[^"\'\s]+)["\']?\)/i', 
    646                                '/url\s*\(["\']?([\.\/]+[^"\'\s]+)["\']?\)/i', 
    647                                '/<script.+<\/script>/Umis'); 
    648  
    649       $remote_replaces = array('<img \\1src=\\2./program/blocked.gif\\4', 
    650                                '', 
    651                                '', 
    652                                '', 
    653                                'none', 
    654                                'none', 
    655                                ''); 
    656        
    657       // set flag if message containes remote obejcts that where blocked 
    658       foreach ($remote_patterns as $pattern) 
    659         { 
    660         if (preg_match($pattern, $body)) 
    661           { 
    662           $REMOTE_OBJECTS = TRUE; 
    663           break; 
    664           } 
    665         } 
    666  
    667       $body = preg_replace($remote_patterns, $remote_replaces, $body); 
    668       } 
    669  
    670     return Q(rcmail_html_filter($body), 'show', FALSE); 
    671     } 
    672  
     530  else if ($part->ctype_secondary == 'html') { 
     531    // clean HTML with washhtml by Frederic Motte 
     532    $body = washtml::wash($part->body, array( 
     533      'show_washed' => false, 
     534      'allow_remote' => $safe, 
     535      'blocked_src' => "./program/blocked.gif", 
     536      'charset' => 'UTF-8', 
     537      'cid_map' => $part->replaces, 
     538      ), $full_inline); 
     539 
     540    $REMOTE_OBJECTS = !$full_inline; 
     541 
     542    return $body; 
     543  } 
    673544  // text/enriched 
    674   if ($part->ctype_secondary=='enriched') 
    675     { 
     545  else if ($part->ctype_secondary=='enriched') { 
    676546    return Q(enriched_to_html($body), 'show'); 
    677     } 
     547  } 
    678548  else 
    679     { 
    680     // make links and email-addresses clickable 
    681     $convert_patterns = $convert_replaces = $replace_strings = array(); 
    682      
    683     $url_chars = 'a-z0-9_\-\+\*\$\/&%=@#:;'; 
    684     $url_chars_within = '\?\.~,!'; 
    685  
    686     $convert_patterns[] = "/([\w]+):\/\/([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie"; 
    687     $convert_replaces[] = "rcmail_str_replacement('<a href=\"\\1://\\2\" target=\"_blank\">\\1://\\2</a>', \$replace_strings)"; 
    688  
    689     $convert_patterns[] = "/([^\/:]|\s)(www\.)([a-z0-9\-]{2,}[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie"; 
    690     $convert_replaces[] = "rcmail_str_replacement('\\1<a href=\"http://\\2\\3\" target=\"_blank\">\\2\\3</a>', \$replace_strings)"; 
    691      
    692     $convert_patterns[] = '/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/ie'; 
    693     $convert_replaces[] = "rcmail_str_replacement('<a href=\"mailto:\\1\" onclick=\"return ".JS_OBJECT_NAME.".command(\'compose\',\'\\1\',this)\">\\1</a>', \$replace_strings)"; 
    694      
     549    $body = $part->body; 
     550 
     551 
     552  /**** assert plaintext ****/ 
     553 
     554  // make links and email-addresses clickable 
     555  $convert_patterns = $convert_replaces = $replace_strings = array(); 
     556   
     557  $url_chars = 'a-z0-9_\-\+\*\$\/&%=@#:;'; 
     558  $url_chars_within = '\?\.~,!'; 
     559 
     560  $convert_patterns[] = "/([\w]+):\/\/([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie"; 
     561  $convert_replaces[] = "rcmail_str_replacement('<a href=\"\\1://\\2\" target=\"_blank\">\\1://\\2</a>', \$replace_strings)"; 
     562 
     563  $convert_patterns[] = "/([^\/:]|\s)(www\.)([a-z0-9\-]{2,}[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie"; 
     564  $convert_replaces[] = "rcmail_str_replacement('\\1<a href=\"http://\\2\\3\" target=\"_blank\">\\2\\3</a>', \$replace_strings)"; 
     565   
     566  $convert_patterns[] = '/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/ie'; 
     567  $convert_replaces[] = "rcmail_str_replacement('<a href=\"mailto:\\1\" onclick=\"return ".JS_OBJECT_NAME.".command(\'compose\',\'\\1\',this)\">\\1</a>', \$replace_strings)"; 
     568   
    695569//    if ($part->ctype_parameters['format'] != 'flowed') 
    696570//      $body = wordwrap(trim($body), 80); 
    697571 
    698     $body = preg_replace($convert_patterns, $convert_replaces, $body); 
    699  
    700     // split body into single lines 
    701     $a_lines = preg_split('/\r?\n/', $body); 
    702     $quote_level = 0; 
    703  
    704     // colorize quoted parts 
    705     for($n=0; $n<sizeof($a_lines); $n++) 
    706       { 
    707       $line = $a_lines[$n]; 
    708       $quotation = ''; 
    709       $q = 0; 
    710        
    711       if (preg_match('/^(>+\s*)+/', $line, $regs)) 
    712         { 
    713         $q    = strlen(preg_replace('/\s/', '', $regs[0])); 
    714         $line = substr($line, strlen($regs[0])); 
    715  
    716         if ($q > $quote_level) 
    717           $quotation = str_repeat('<blockquote>', $q - $quote_level); 
    718         else if ($q < $quote_level) 
    719           $quotation = str_repeat("</blockquote>", $quote_level - $q); 
    720         } 
    721       else if ($quote_level > 0) 
    722         $quotation = str_repeat("</blockquote>", $quote_level); 
    723  
    724       $quote_level = $q; 
    725       $a_lines[$n] = $quotation . Q($line, 'replace', FALSE); 
    726       } 
    727  
    728     // insert the links for urls and mailtos 
    729     $body = preg_replace("/##string_replacement\{([0-9]+)\}##/e", "\$replace_strings[\\1]", join("\n", $a_lines)); 
    730      
    731     return "<div class=\"pre\">".$body."\n</div>"; 
    732     } 
    733   } 
    734  
    735  
    736  
    737 // add a string to the replacement array and return a replacement string 
     572  // search for patterns like links and e-mail addresses 
     573  $body = preg_replace($convert_patterns, $convert_replaces, $body); 
     574 
     575  // split body into single lines 
     576  $a_lines = preg_split('/\r?\n/', $body); 
     577  $quote_level = 0; 
     578 
     579  // colorize quoted parts 
     580  for ($n=0; $n < sizeof($a_lines); $n++) { 
     581    $line = $a_lines[$n]; 
     582    $quotation = ''; 
     583    $q = 0; 
     584     
     585    if (preg_match('/^(>+\s*)+/', $line, $regs)) { 
     586      $q    = strlen(preg_replace('/\s/', '', $regs[0])); 
     587      $line = substr($line, strlen($regs[0])); 
     588 
     589      if ($q > $quote_level) 
     590        $quotation = str_repeat('<blockquote>', $q - $quote_level); 
     591      else if ($q < $quote_level) 
     592        $quotation = str_repeat("</blockquote>", $quote_level - $q); 
     593    } 
     594    else if ($quote_level > 0) 
     595      $quotation = str_repeat("</blockquote>", $quote_level); 
     596 
     597    $quote_level = $q; 
     598    $a_lines[$n] = $quotation . Q($line, 'replace', false);  // htmlquote plaintext 
     599  } 
     600 
     601  // insert the links for urls and mailtos 
     602  $body = preg_replace("/##string_replacement\{([0-9]+)\}##/e", "\$replace_strings[\\1]", join("\n", $a_lines)); 
     603   
     604  return "<div class=\"pre\">".$body."\n</div>"; 
     605  } 
     606 
     607 
     608 
     609/** 
     610 * add a string to the replacement array and return a replacement string 
     611 */ 
    738612function rcmail_str_replacement($str, &$rep) 
    739613  { 
     
    744618 
    745619 
    746 function rcmail_parse_message(&$structure, $arg=array(), $recursive=FALSE) 
    747   { 
    748   global $IMAP; 
    749   static $sa_inline_objects = array(); 
    750  
    751   // arguments are: (bool)$prefer_html, (string)$get_url 
    752   extract($arg); 
    753  
    754   $a_attachments = array(); 
    755   $a_return_parts = array(); 
    756   $out = ''; 
    757  
    758   $message_ctype_primary = strtolower($structure->ctype_primary); 
    759   $message_ctype_secondary = strtolower($structure->ctype_secondary); 
    760  
    761   // show message headers 
    762   if ($recursive && is_array($structure->headers) && isset($structure->headers['subject'])) 
    763     { 
    764     $c = new stdClass; 
    765     $c->type = 'headers'; 
    766     $c->headers = &$structure->headers; 
    767     $a_return_parts[] = $c; 
    768     } 
    769  
    770   // print body if message doesn't have multiple parts 
    771   if ($message_ctype_primary=='text') 
    772     { 
    773     $structure->type = 'content'; 
    774     $a_return_parts[] = &$structure; 
    775     } 
    776      
    777   // message contains alternative parts 
    778   else if ($message_ctype_primary=='multipart' && $message_ctype_secondary=='alternative' && is_array($structure->parts)) 
    779     { 
    780     // get html/plaintext parts 
    781     $plain_part = $html_part = $print_part = $related_part = NULL; 
    782      
    783     foreach ($structure->parts as $p => $sub_part) 
    784       { 
    785       $rel_parts = $attachmnts = null; 
    786       $sub_ctype_primary = strtolower($sub_part->ctype_primary); 
    787       $sub_ctype_secondary = strtolower($sub_part->ctype_secondary); 
    788  
    789       // check if sub part is  
    790       if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='plain') 
    791         $plain_part = $p; 
    792       else if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='html') 
    793         $html_part = $p; 
    794       else if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='enriched') 
    795         $enriched_part = $p; 
    796       else if ($sub_ctype_primary=='multipart' && ($sub_ctype_secondary=='related' || $sub_ctype_secondary=='mixed')) 
    797         $related_part = $p; 
    798       } 
    799        
    800     // parse related part (alternative part could be in here) 
    801     if ($related_part!==NULL) 
    802     { 
    803       list($rel_parts, $attachmnts) = rcmail_parse_message($structure->parts[$related_part], $arg, TRUE); 
    804       $a_attachments = array_merge($a_attachments, $attachmnts); 
    805     } 
    806      
    807     // merge related parts if any 
    808     if ($rel_parts && $prefer_html && !$html_part) 
    809       $a_return_parts = array_merge($a_return_parts, $rel_parts); 
    810  
    811     // choose html/plain part to print 
    812     else if ($html_part!==NULL && $prefer_html) 
    813       $print_part = &$structure->parts[$html_part]; 
    814     else if ($enriched_part!==NULL) 
    815       $print_part = &$structure->parts[$enriched_part]; 
    816     else if ($plain_part!==NULL) 
    817       $print_part = &$structure->parts[$plain_part]; 
    818  
    819     // show message body 
    820     if (is_object($print_part)) 
    821       { 
    822       $print_part->type = 'content'; 
    823       $a_return_parts[] = $print_part; 
    824       } 
    825     // show plaintext warning 
    826     else if ($html_part!==NULL && empty($a_return_parts)) 
    827       { 
    828       $c = new stdClass; 
    829       $c->type = 'content'; 
    830       $c->body = rcube_label('htmlmessage'); 
    831       $c->ctype_primary = 'text'; 
    832       $c->ctype_secondary = 'plain'; 
    833        
    834       $a_return_parts[] = $c; 
    835       } 
    836                                  
    837     // add html part as attachment 
    838     if ($html_part!==NULL && $structure->parts[$html_part]!==$print_part) 
    839       { 
    840       $html_part = &$structure->parts[$html_part]; 
    841       $html_part->filename = rcube_label('htmlmessage'); 
    842       $html_part->mimetype = 'text/html'; 
    843        
    844       $a_attachments[] = $html_part; 
    845       } 
    846     } 
    847  
    848   // message contains multiple parts 
    849   else if (is_array($structure->parts) && !empty($structure->parts)) 
    850     { 
    851     for ($i=0; $i<count($structure->parts); $i++) 
    852       { 
    853       $mail_part = &$structure->parts[$i]; 
    854       $primary_type = strtolower($mail_part->ctype_primary); 
    855       $secondary_type = strtolower($mail_part->ctype_secondary); 
    856  
    857       // multipart/alternative 
    858       if ($primary_type=='multipart') 
    859         { 
    860         list($parts, $attachmnts) = rcmail_parse_message($mail_part, $arg, TRUE); 
    861  
    862         $a_return_parts = array_merge($a_return_parts, $parts); 
    863         $a_attachments = array_merge($a_attachments, $attachmnts); 
    864         } 
    865  
    866       // part text/[plain|html] OR message/delivery-status 
    867       else if (($primary_type=='text' && ($secondary_type=='plain' || $secondary_type=='html') && $mail_part->disposition!='attachment') || 
    868                ($primary_type=='message' && ($secondary_type=='delivery-status' || $secondary_type=='disposition-notification'))) 
    869         { 
    870         $mail_part->type = 'content'; 
    871         $a_return_parts[] = $mail_part; 
    872         } 
    873  
    874       // part message/* 
    875       else if ($primary_type=='message') 
    876         { 
    877         list($parts, $attachmnts) = rcmail_parse_message($mail_part, $arg, TRUE); 
    878            
    879         $a_return_parts = array_merge($a_return_parts, $parts); 
    880         $a_attachments = array_merge($a_attachments, $attachmnts); 
    881         } 
    882          
    883       // ignore "virtual" protocol parts 
    884       else if ($primary_type=='protocol') 
    885         continue; 
    886  
    887       // part is file/attachment 
    888       else if ($mail_part->disposition=='attachment' || $mail_part->disposition=='inline' || $mail_part->headers['content-id'] || 
    889                (empty($mail_part->disposition) && $mail_part->filename)) 
    890         { 
    891         // skip apple resource forks 
    892         if ($message_ctype_secondary=='appledouble' && $secondary_type=='applefile') 
    893           continue; 
    894  
    895         // part belongs to a related message 
    896         if ($message_ctype_secondary=='related' && $mail_part->headers['content-id']) 
    897           { 
    898           $mail_part->content_id = preg_replace(array('/^</', '/>$/'), '', $mail_part->headers['content-id']); 
    899           $sa_inline_objects[] = $mail_part; 
    900           } 
    901         // is regular attachment 
    902         else 
    903           { 
    904           if (!$mail_part->filename) 
    905             $mail_part->filename = 'Part '.$mail_part->mime_id; 
    906           $a_attachments[] = $mail_part; 
    907           } 
    908         } 
    909       } 
    910  
    911     // if this was a related part try to resolve references 
    912     if ($message_ctype_secondary=='related' && sizeof($sa_inline_objects)) 
    913       { 
    914       $a_replaces = array(); 
    915          
    916       foreach ($sa_inline_objects as $inline_object) 
    917         $a_replaces['cid:'.$inline_object->content_id] = htmlspecialchars(sprintf($get_url, $inline_object->mime_id)); 
    918        
    919       // add replace array to each content part 
    920       // (will be applied later when part body is available) 
    921       for ($i=0; $i<count($a_return_parts); $i++) 
    922         { 
    923         if ($a_return_parts[$i]->type=='content') 
    924           $a_return_parts[$i]->replaces = $a_replaces; 
    925         } 
    926       } 
    927     } 
    928  
    929   // message is single part non-text 
    930   else if ($structure->filename) 
    931     $a_attachments[] = $structure; 
    932  
    933   return array($a_return_parts, $a_attachments); 
    934   } 
    935  
    936  
    937  
    938  
    939 // return table with message headers 
     620 
     621/** 
     622 * return table with message headers 
     623 */ 
    940624function rcmail_message_headers($attrib, $headers=NULL) 
    941625  { 
     
    990674 
    991675 
    992  
     676/** 
     677 * 
     678 */ 
    993679function rcmail_message_body($attrib) 
    994680  { 
     
    1029715         
    1030716        if ($part->ctype_secondary != 'plain') 
    1031           $out .= rcmail_sanitize_html($body, $attrib['id']); 
     717          $out .= rcmail_html4inline($body, $attrib['id']); 
    1032718        else 
    1033719          $out .= $body; 
     
    1069755 
    1070756 
    1071 // modify a HTML message that it can be displayed inside a HTML page 
    1072 function rcmail_sanitize_html($body, $container_id) 
    1073   { 
    1074   // remove any null-byte characters before parsing 
    1075   $body = preg_replace('/\x00/', '', $body); 
    1076    
     757/** 
     758 * modify a HTML message that it can be displayed inside a HTML page 
     759 */ 
     760function rcmail_html4inline($body, $container_id) 
     761  { 
    1077762  $base_url = ""; 
    1078763  $last_style_pos = 0; 
     
    1094779    $body_lc = strtolower($body); 
    1095780    $last_style_pos = $pos2; 
    1096     } 
    1097  
    1098  
    1099   // remove SCRIPT tags 
    1100   foreach (array('script', 'applet', 'object', 'embed', 'iframe') as $tag) 
    1101     { 
    1102     while (($pos = strpos($body_lc, '<'.$tag)) && (($pos2 = strpos($body_lc, '</'.$tag.'>', $pos)) || ($pos3 = strpos($body_lc, '>', $pos)))) 
    1103       { 
    1104       $end = $pos2 ? $pos2 + strlen('</'.$tag.'>') : $pos3 + 1; 
    1105       $body = substr($body, 0, $pos) . substr($body, $end, strlen($body)-$end); 
    1106       $body_lc = strtolower($body); 
    1107       } 
    1108     } 
    1109  
    1110   // replace event handlers on any object 
    1111   while ($body != $prev_body) 
    1112     { 
    1113     $prev_body = $body; 
    1114     $body = preg_replace('/(<[^!][^>]*\s)on(?:load|unload|click|dblclick|mousedown|mouseup|mouseover|mousemove|mouseout|focus|blur|keypress|keydown|keyup|submit|reset|select|change)=([^>]+>)/im', '$1__removed=$2', $body); 
    1115     $body = preg_replace('/(<[^!][^>]*\shref=["\']?)(javascript:)([^>]*?>)/im', '$1null:$3', $body); 
    1116781    } 
    1117782 
     
    1139804 
    1140805  $out = preg_replace( 
    1141     array( 
    1142       '/<body([^>]*)>/i', 
    1143       '/<\/body>/i', 
    1144     ), 
    1145     array( 
    1146       '<div class="rcmBody"\\1>', 
    1147       '</div>', 
    1148     ), 
     806    array('/<body([^>]*)>/i', '/<\/body>/i'), 
     807    array('<div class="rcmBody"\\1>', '</div>'), 
    1149808    $out); 
    1150809 
     
    1156815 
    1157816 
    1158 // parse link attributes and set correct target 
     817/** 
     818 * parse link attributes and set correct target 
     819 */ 
    1159820function rcmail_alter_html_link($tag, $attrs, $container_id) 
    1160821  { 
     
    1177838 
    1178839 
    1179 // decode address string and re-format it as HTML links 
     840/** 
     841 * decode address string and re-format it as HTML links 
     842 */ 
    1180843function rcmail_address_string($input, $max=NULL, $addicon=NULL) 
    1181844  { 
     
    1278941 
    1279942 
    1280 // clear message composing settings 
     943/** 
     944 * clear message composing settings 
     945 */ 
    1281946function rcmail_compose_cleanup() 
    1282947  { 
Note: See TracChangeset for help on using the changeset viewer.