4 * @author Brian Wong <bwsource@users.sourceforge.net>
8 * Copyright (C) 2003 - 2007 MailZu
9 * License: GPL, see LICENSE
12 * Base directory of application
14 @define
('BASE_DIR', dirname(__FILE__
) . '/..');
18 include_once('CmnFns.class.php');
22 if ($GLOBALS['conf']['app']['safeMode']) {
23 ini_set('include_path', ( dirname(__FILE__
) . '/pear/' . PATH_SEPARATOR
. ini_get('include_path') ));
24 include_once('pear/Mail/mimeDecode.php');
27 include_once('Mail/mimeDecode.php');
31 * Include htmlfilter class
33 include_once('lib/htmlfilter.php');
37 * Provide all MIME functionality
42 * $param The mime structure object
44 function GetCtype($struct) {
45 $ctype_p = strtolower(trim($struct->ctype_primary
));
46 $ctype_s = strtolower(trim($struct->ctype_secondary
));
47 $type = $ctype_p . '/' . $ctype_s;
52 * Recursively parse MIME structure
53 * $param The mime structure object
58 function MsgParseBody($struct) {
62 $ctype_p = strtolower(trim($struct->ctype_primary
));
63 $ctype_s = strtolower(trim($struct->ctype_secondary
));
69 // Handle multipart/alternative parts
70 $alt_entity = FindMultiAlt($struct->parts
);
71 // Ignore if we return false NEEDS WORK
72 if ($alt_entity) MsgParseBody($alt_entity);
75 // Handle multipart/related parts
76 $rel_entities = FindMultiRel($struct);
77 foreach ($rel_entities as $ent) {
82 // Probably multipart/mixed here
83 // Recursively process nested mime entities
84 if ( is_array($struct->parts
) ||
is_object($struct->parts
) ) {
85 foreach ($struct->parts
as $cur_part) {
86 MsgParseBody($cur_part);
89 $errors['Invalid or Corrupt MIME Detected.'] = true;
96 // Do not display attached text types
97 if ($attachment = $struct->d_parameters
['filename'] or
98 $attachment = $struct->d_parameters
['name']) {
99 array_push($filelist, $attachment);
105 MsgBodyPlainText($struct->body
);
109 MsgBodyHtmlText($struct->body
);
111 // Text type we do not support
113 $errors['Portions of text could not be displayed'] = true;
118 // Save the listed filename or notify the
119 // reader that this mail is not displayed completely
120 $attachment = $struct->d_parameters
['filename'];
121 $attachment ?
array_push($filelist, $attachment) : $errors['Unsupported MIME objects present'] = true;
127 * Get the best MIME entity for multipart/alternative
128 * Adapted from SqurrelMail
129 * $param Array of MIME entities
130 * $return Single MIME entity
132 function FindMultiAlt($parts) {
133 $alt_pref = array ('text/plain', 'text/html');
135 // Bad Headers sometimes have invalid MIME....
136 if ( is_array($parts) ||
is_object($parts) ) {
137 foreach ($parts as $cur_part) {
138 $type = GetCtype($cur_part);
139 if ($type == 'multipart/related') {
140 $type = $cur_part->d_parameters
['type'];
141 // Mozilla bug. Mozilla does not provide the parameter type.
142 if (!$type) $type = 'text/html';
144 $altCount = count($alt_pref);
145 for ($j = $best_view; $j < $altCount; ++
$j) {
146 if (($alt_pref[$j] == $type) && ($j >= $best_view)) {
154 $errors['Invalid or Corrupt MIME Detected.'] = true;
159 * Get the list of related entities for multipart/related
160 * Adapted from SqurrelMail
161 * $param multipart/alternative structure
162 * @return List of MIME entities
164 function FindMultiRel($struct) {
166 $type = $struct->d_parameters
['type'];
167 // Mozilla bug. Mozilla does not provide the parameter type.
168 if (!$type) $type = 'text/html';
169 // Bad Headers sometimes have invalid MIME....
170 if ( is_array($struct->parts
) ||
is_object($struct->parts
) ) {
171 foreach ($struct->parts
as $part) {
172 if (GetCtype($part) == $type ||
GetCtype($part) == "multipart/alternative") {
173 array_push($entities,$part);
177 $errors['Invalid or Corrupt MIME Detected.'] = true;
182 // Wrapper script for htmlfilter. Settings taken
184 function sanitizeHTML($body) {
185 if (isset($_COOKIE['lang']) &&
186 file_exists("img/".substr($_COOKIE['lang'],0,2).".blocked_img.png")) {
187 $secremoveimg = "img/".substr($_COOKIE['lang'],0,2).".blocked_img.png";
189 $secremoveimg = "img/blocked_img.png";
205 $rm_tags_with_content = Array(
215 $self_closing_tags = Array(
222 $force_tag_closing = true;
224 $rm_attnames = Array(
235 $bad_attvals = Array(
238 "/^src|background/i" =>
241 "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
242 "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
243 "/^([\'\"])\s*about\s*:.*([\'\"])/si",
244 "/^([\'\"])\s*https*:.*([\'\"])/si",
245 "/^([\'\"])\s*cid*:.*([\'\"])/si"
248 "\\1$secremoveimg\\2",
249 "\\1$secremoveimg\\2",
250 "\\1$secremoveimg\\2",
251 "\\1$secremoveimg\\2",
252 "\\1$secremoveimg\\2"
258 "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
259 "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
260 "/^([\'\"])\s*about\s*:.*([\'\"])/si"
276 "/url\s*\(\s*([\'\"])\s*\S+script\s*:.*([\'\"])\s*\)/si",
277 "/url\s*\(\s*([\'\"])\s*mocha\s*:.*([\'\"])\s*\)/si",
278 "/url\s*\(\s*([\'\"])\s*about\s*:.*([\'\"])\s*\)/si",
279 "/(.*)\s*:\s*url\s*\(\s*([\'\"]*)\s*\S+script\s*:.*([\'\"]*)\s*\)/si",
280 "/url\(([\'\"])\s*https*:.*([\'\"])\)/si"
293 "url(\\1$secremoveimg\\1)"
299 $add_attr_to_tag = Array(
301 Array('target'=>'"_new"'
305 $trusted_html = sanitize($body,
307 $rm_tags_with_content,
315 return $trusted_html;