Permalink
Browse files

fix bug #18578 - support filename*0*=ENClangname_encoded, and improve…

… multipart filename support in headers

git-svn-id: http://svn.php.net/repository/pear/packages/Mail_Mime/trunk@315264 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information...
1 parent e06399d commit c0977a162748e0e64412ea5f1503b313867dda75 @roojs roojs committed Aug 22, 2011
Showing with 61 additions and 40 deletions.
  1. +61 −40 mimeDecode.php
View
@@ -476,14 +476,24 @@ function _parseHeaders($input)
* robust as it could be. Eg. header comments
* in the wrong place will probably break it.
*
+ * Extra things this can handle
+ * filename*0=......
+ * filename*1=......
+ *
+ * This is where lines are broken in, and need merging.
+ *
+ * filename*0*=ENC'lang'urlencoded data.
+ * filename*1*=ENC'lang'urlencoded data.
+ *
+ *
+ *
* @param string Header value to parse
* @return array Contains parsed result
* @access private
*/
function _parseHeaderValue($input)
{
-
- if (($pos = strpos($input, ';')) === false) {
+ if (($pos = strpos($input, ';')) === false) {
$input = $this->_decode_headers ? $this->_decodeHeader($input) : $input;
$return['value'] = trim($input);
return $return;
@@ -536,7 +546,6 @@ function _parseHeaderValue($input)
if ($key) { // a key without a value..
$key= trim($key);
$return['other'][$key] = '';
- $return['other'][strtolower($key)] = '';
}
$key = '';
}
@@ -553,7 +562,11 @@ function _parseHeaderValue($input)
$i++;
continue; // skip leading spaces after '=' or after '"'
}
- if (!$escaped && ($c == '"' || $c == "'")) {
+
+ // do not de-quote 'xxx*= itesm..
+ $key_is_trans = $key[strlen($key)-1] == '*';
+
+ if (!$key_is_trans && !$escaped && ($c == '"' || $c == "'")) {
// start quoted area..
$q = $c;
// in theory should not happen raw text in value part..
@@ -564,26 +577,8 @@ function _parseHeaderValue($input)
}
// got end....
if (!$escaped && $c == ';') {
-
- $val = trim($val);
- $added = false;
- if (preg_match('/\*[0-9]+$/', $key)) {
- // this is the extended aaa*0=...;aaa*1=.... code
- // it assumes the pieces arrive in order, and are valid...
- $key = preg_replace('/\*[0-9]+$/', '', $key);
- if (isset($return['other'][$key])) {
- $return['other'][$key] .= $val;
- if (strtolower($key) != $key) {
- $return['other'][strtolower($key)] .= $val;
- }
- $added = true;
- }
- // continue and use standard setters..
- }
- if (!$added) {
- $return['other'][$key] = $val;
- $return['other'][strtolower($key)] = $val;
- }
+
+ $return['other'][$key] = trim($val);
$val = false;
$key = '';
$lq = false;
@@ -598,7 +593,7 @@ function _parseHeaderValue($input)
// state - in quote..
if (!$escaped && $c == $q) { // potential exit state..
-
+
// end of quoted string..
$lq = $q;
$q = false;
@@ -615,29 +610,55 @@ function _parseHeaderValue($input)
if (strlen(trim($key)) || $val !== false) {
$val = trim($val);
- $added = false;
- if ($val !== false && preg_match('/\*[0-9]+$/', $key)) {
- // no dupes due to our crazy regexp.
- $key = preg_replace('/\*[0-9]+$/', '', $key);
- if (isset($return['other'][$key])) {
- $return['other'][$key] .= $val;
- if (strtolower($key) != $key) {
- $return['other'][strtolower($key)] .= $val;
- }
- $added = true;
+
+ $return['other'][$key] = $val;
+ }
+
+
+ $clean_others = array();
+ // merge added values. eg. *1[*]
+ foreach($return['other'] as $key =>$val) {
+ if (preg_match('/\*[0-9]+\**$/', $key)) {
+ $key = preg_replace('/(.*)\*[0-9]+(\**)$/', '\1\2', $key);
+ if (isset($clean_others[$key])) {
+ $clean_others[$key] .= $val;
+ continue;
}
- // continue and use standard setters..
+
}
- if (!$added) {
- $return['other'][$key] = $val;
- $return['other'][strtolower($key)] = $val;
+ $clean_others[$key] = $val;
+
+ }
+
+ // handle language translation of '*' ending others.
+ foreach( $clean_others as $key =>$val) {
+ if ( $key[strlen($key)-1] != '*') {
+ $clean_others[strtolower($key)] = $val;
+ continue;
}
+ unset($clean_others[$key]);
+ $key = substr($key,0,-1);
+ //extended-initial-value := [charset] "'" [language] "'"
+ // extended-other-values
+ $match = array();
+ $info = preg_match("/^([^']+)'([^']*)'(.*)$/", $val, $match);
+
+ $clean_others[$key] = urldecode($match[3]);
+ $clean_others[strtolower($key)] = $clean_others[$key];
+ $clean_others[strtolower($key).'-charset'] = $match[1];
+ $clean_others[strtolower($key).'-language'] = $match[2];
+
+
}
+
+
+ $return['other'] = $clean_others;
+
// decode values.
foreach($return['other'] as $key =>$val) {
$return['other'][$key] = $this->_decode_headers ? $this->_decodeHeader($val) : $val;
}
- //print_r($return);
+
return $return;
}

0 comments on commit c0977a1

Please sign in to comment.