X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=banana%2Fmessage.func.inc.php;h=8df5cd4dd2a61c1084f1fc8431ab84acf68ace83;hb=3958da5df280bd8b4125ca6013c3fda9f538ae96;hp=816417238ed909f3928dfa9dc1e2782fcce33aaa;hpb=3c3a3ce3a8566a0377956efe540a2335ea22f74e;p=banana.git diff --git a/banana/message.func.inc.php b/banana/message.func.inc.php index 8164172..8df5cd4 100644 --- a/banana/message.func.inc.php +++ b/banana/message.func.inc.php @@ -72,30 +72,50 @@ function banana_unflowed($text) return $text; } -function banana_wordwrap($text, $quote_level) +function banana_wordwrap($text, $quote_level = 0) { if ($quote_level > 0) { $length = Banana::$msgshow_wrap - $quote_level - 1; return banana_quote(wordwrap($text, $length), $quote_level); - } return wordwrap($text, Banana::$msgshow_wrap); } function banana_catchFormats($text) { - $formatting = Array('/' => 'em', // match / first in order not to match closing markups <> - '_' => 'u', - '*' => 'strong'); + $formatting = Array('em' => array('\B\/\b', '\b\/\B'), + 'u' => array('\b_', '_\b'), + 'strong' => array('\B\*\b', '\b\*\B')); $url = Banana::$msgshow_url; preg_match_all("/$url/ui", $text, $urls); - $text = str_replace($urls[0], "&&&urls&&&", $text); - foreach ($formatting as $limit=>$mark) { - $limit = preg_quote($limit, '/'); - $text = preg_replace("/$limit\\b(.*?)\\b$limit/s", + $urls = $urls[0]; + $replace = $urls; + rsort($replace); + $text = str_replace($replace, "&&&urls&&&", $text); + foreach ($formatting as $mark=>$limit) { + list($ll, $lr) = $limit; + $text = preg_replace('/' . $ll . '(\w+?)' . $lr . '/us', "<$mark>\\1", $text); } - return preg_replace('/&&&urls&&&/e', 'array_shift($urls[0])', $text); + return preg_replace('/&&&urls&&&/e', 'array_shift($urls)', $text); +} + +/** Build a flowed text from plain text + */ +function banana_flow($text) +{ + $lines = explode("\n", $text); + $text = ''; + while (!is_null($line = array_shift($lines))) { + if ($line != '-- ') { + $level = 0; + $line = banana_removeQuotes($line, $level); + $text .= rtrim(str_replace("\n", " \n", banana_wordwrap($line, $level))) . "\n"; + } else { + $text .= $line . "\n"; + } + } + return $text; } // {{{ URL Catcher tools @@ -123,7 +143,7 @@ function banana__catchMailLink($email) $mid = '<' . $email . '>'; if (isset(Banana::$spool->ids[$mid])) { return Banana::$page->makeLink(Array('group' => Banana::$group, - 'artid' => Banana::$spool->ids[$mid], + 'artid' => Banana::$spool->ids[$mid]->id, 'text' => $email)); } elseif (strpos($email, '$') !== false) { return $email; @@ -187,7 +207,7 @@ function banana_plainTextToHtml($text, $strict = true) $text = banana_catchURLs($text); $text = banana_catchQuotes($text, $strict); $text = banana_catchSignature($text); - return banana_cleanHtml('
' . $text . '
'); + return '
' . $text . '
'; } function banana_wrap($text, $base_level = 0, $strict = true) @@ -203,7 +223,7 @@ function banana_wrap($text, $base_level = 0, $strict = true) if (!empty($buffer)) { $text .= banana_wordwrap(implode("\n", $buffer), $level + $base_level) . "\n"; $buffer = array(); - } + } $level = $lvl; } $buffer[] = $line; @@ -214,23 +234,27 @@ function banana_wrap($text, $base_level = 0, $strict = true) return $text; } -function banana_formatPlainText(BananaMimePart &$part, $base_level = 0) +function banana_formatPlainText(BananaMimePart $part, $base_level = 0) { $text = $part->getText(); if ($part->isFlowed()) { $text = banana_unflowed($text); } - $text = banana_wrap($text, $base_level, $part->isFlowed()); - return banana_plainTextToHtml($text, $part->isFlowed()); + if (function_exists('hook_formatPart') && ($ret = hook_formatPart($text, $part, $base_level))) { + return $ret; + } else { + $text = banana_wrap($text, $base_level, $part->isFlowed()); + return banana_plainTextToHtml($text, $part->isFlowed()); + } } -function banana_quotePlainText(BananaMimePart &$part) +function banana_quotePlainText(BananaMimePart $part) { $text = $part->getText(); if ($part->isFlowed()) { $text = banana_unflowed($text); } - return banana_wrap($text, 1); + return banana_quote($text, 1); } // }}} @@ -251,40 +275,147 @@ function banana_removeEvilAttributes($tagSource) $stripAttrib = 'javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|'. 'onmousemove|onmouseout|onkeypress|onkeydown|onkeyup'; return stripslashes(preg_replace("/$stripAttrib/i", '', $tagSource)); -} +} + +function banana_cleanStyles($tag, $attributes) +{ + static $td_style, $conv, $size_conv; + if (!isset($td_style)) { + $conv = array('style' => 'style', 'width' => 'width', 'height' => 'height', 'border' => 'border-size', + 'size' => 'font-size', 'align' => 'text-align', 'valign' => 'vertical-align', 'face' => 'font', + 'bgcolor' => 'background-color', 'color' => 'color', 'style' => 'style', + 'cellpadding' => 'padding', 'cellspacing' => 'border-spacing'); + $size_conv = array(1 => 'xx-small', 2 => 'x-small', 3 => 'small', 4 => 'medium', 5 => 'large', + 6 => 'x-large', 7 => 'xx-large', + '-2' => 'xx-small', '-1' => 'x-small', '+1' => 'medium', '+2' => 'large', + '+3' => 'x-large', '+4' => 'xx-large'); + $td_style = array(); + } + if ($tag == 'table') { + array_unshift($td_style, ''); + } + if ($tag == '/table') { + array_shift($td_style); + } + if ($tag{0} == '/') { + return ''; + } + if ($tag == 'td') { + $style = $td_style[0]; + } else { + $style = ''; + } + $attributes = str_replace(array("\n", "\r"), ' ', stripslashes($attributes)); + $attributes = str_replace(array('= "', '= \''), array('="', '=\''), $attributes); + foreach ($conv as $att=>$stl) { + $pattern = '/\b' . preg_quote($att, '/') . '=([\'"])?(.+?)(?(1)\1|(?:$| ))/i'; + if (preg_match($pattern, $attributes, $matches)) { + $attributes = preg_replace($pattern, '', $attributes); + $val = $matches[2]; + if ($att == 'cellspacing' && strpos($style, 'border-collapse') === false) { + $style = "border-collapse: separate; border-spacing: $val $val; " . $style; + } elseif ($att == 'cellpadding' && $tag == 'table') { + $td_style[0] = "$stl: {$val}px; "; + } elseif ($att == 'style') { + $val = rtrim($val, ' ;'); + $style .= "$val; "; + } elseif ($att == 'size') { + $val = $size_conv[$val]; + $style = "$stl: $val; " . $style; + } elseif (is_numeric($val)) { + $style = "$stl: {$val}px; " . $style; + } else { + $style = "$stl: $val; " . $style; + } + } + } + if (!empty($style)) { + $style = 'style="' . $style . '" '; + } + return ' ' . $style . trim($attributes); +} + +function banana__filterCss($text) +{ + $text = preg_replace("/(,[\s\n\r]*)/s", '\1 .banana .message .body .html ', $text); + return '.banana .message .body .html ' . $text; +} + +function banana_filterCss($css) +{ + preg_match_all("/(^|\n|,\s*)\s*([\#\.@\w][^;\{\}\<]*?[\{])/s", $css, $matches); + $css = preg_replace("/(^|\n)\s*([\#\.@\w][^;\{\}\<]*?)([\{])/se", '"\1" . banana__filterCss("\2") . "\3"', $css); + $css = preg_replace('/ body\b/i', '', $css); + if (!Banana::$msgshow_externalimages) { + if (preg_match('!url\([^:\)]+:(//|\\\).*?\)!i', $css)) { + $css = preg_replace('!url\([^:\)]+:(//|\\\).*?\)!i', 'url(invalid-image.png)', $css); + Banana::$msgshow_hasextimages = true; + } + } + return $css; +} /** * @return string * @param string * @desc Strip forbidden tags and delegate tag-source check to removeEvilAttributes() */ -function banana_cleanHtml($source) +function banana_cleanHtml($source, $to_xhtml = false) { - $allowedTags = '