summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2014-10-26 09:34:24 +0100
committerAleksander Machniak <alec@alec.pl>2014-10-26 09:34:24 +0100
commit2da8300fb7bb7b0a386d334d4c82a2ffbe3d9331 (patch)
tree40d2a54eb7a90493e69e70dc34f33eebd88553ab
parent3350458b87b84a613b29c5676262be178e7a46e4 (diff)
Correctly detect charset of attachment names in TNEF messages
-rw-r--r--program/lib/Roundcube/rcube_message.php57
1 files changed, 56 insertions, 1 deletions
diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php
index 4f0f0fd1f..0d33ba411 100644
--- a/program/lib/Roundcube/rcube_message.php
+++ b/program/lib/Roundcube/rcube_message.php
@@ -858,7 +858,7 @@ class rcube_message
foreach ($tnef_arr as $pid => $winatt) {
$tpart = new rcube_message_part;
- $tpart->filename = trim($winatt['name']);
+ $tpart->filename = $this->fix_attachment_name(trim($winatt['name']), $part);
$tpart->encoding = 'stream';
$tpart->ctype_primary = trim(strtolower($winatt['type']));
$tpart->ctype_secondary = trim(strtolower($winatt['subtype']));
@@ -931,6 +931,61 @@ class rcube_message
return $parts;
}
+ /**
+ * Fix attachment name encoding if needed/possible
+ */
+ protected function fix_attachment_name($name, $part)
+ {
+ if ($name == rcube_charset::clean($name)) {
+ return $name;
+ }
+
+ // find charset from part or its parent(s)
+ if ($part->charset) {
+ $charsets[] = $part->charset;
+ }
+ else {
+ // check first part (common case)
+ $n = strpos($part->mime_id, '.') ? preg_replace('/\.[0-9]+$/', '', $part->mime_id) . '.1' : 1;
+ if (($_part = $this->mime_parts[$n]) && $_part->charset) {
+ $charsets[] = $_part->charset;
+ }
+
+ // check parents' charset
+ $items = explode('.', $part->mime_id);
+ for ($i = count($items)-1; $i > 0; $i--) {
+ $last = array_pop($items);
+ $parent = $this->mime_parts[join('.', $items)];
+
+ if ($parent && $parent->charset) {
+ $charsets[] = $parent->charset;
+ }
+ }
+ }
+
+ if ($this->headers->charset) {
+ $charsets[] = $this->headers->charset;
+ }
+
+ if (empty($charsets)) {
+ $rcube = rcube::get_instance();
+ $charsets[] = rcube_charset::detect($name, $rcube->config->get('default_charset', RCUBE_CHARSET));
+ }
+
+ foreach (array_unique($charsets) as $charset) {
+ $_name = rcube_charset::convert($name, $charset);
+
+ if ($_name == rcube_charset::clean($_name)) {
+ if (!$part->charset) {
+ $part->charset = $charset;
+ }
+
+ return $_name;
+ }
+ }
+
+ return $name;
+ }
/**
* Deprecated methods (to be removed)