Header parser fixes (ISO_2022_JP charset probles) (Closes #355)

+ Small fixes
This commit is contained in:
RainLoop Team 2014-10-18 01:02:19 +04:00
parent 6b0ca800e8
commit 3a9bc849c9
15 changed files with 131 additions and 59 deletions

View file

@ -174,7 +174,7 @@
AppApp.prototype.recacheInboxMessageList = function ()
{
Remote.messageList(Utils.emptyFunction, 'INBOX', 0, Data.messagesPerPage(), '', true);
Remote.messageList(Utils.emptyFunction, Cache.getFolderInboxName(), 0, Data.messagesPerPage(), '', true);
};
AppApp.prototype.reloadMessageListHelper = function (bEmptyList)
@ -220,7 +220,7 @@
var
bSpam = sSpamFolder === oItem['To'],
bHam = !bSpam && sSpamFolder === oItem['From'] && 'INBOX' === oItem['To']
bHam = !bSpam && sSpamFolder === oItem['From'] && Cache.getFolderInboxName() === oItem['To']
;
Remote.messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'],
@ -320,7 +320,7 @@
nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Spam;
break;
case Enums.FolderType.NotSpam:
oMoveFolder = Cache.getFolderFromCacheList('INBOX');
oMoveFolder = Cache.getFolderFromCacheList(Cache.getFolderInboxName());
break;
case Enums.FolderType.Trash:
oMoveFolder = Cache.getFolderFromCacheList(Data.trashFolder());
@ -612,7 +612,7 @@
{
self.reloadMessageList();
}
else if ('INBOX' === oFolder.fullNameRaw)
else if (Cache.getFolderInboxName() === oFolder.fullNameRaw)
{
self.recacheInboxMessageList();
}
@ -1003,7 +1003,7 @@
if (oCacheFolder)
{
Cache.setFolderToCacheList(sFolderFullNameRaw, oCacheFolder);
Cache.setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw);
Cache.setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw, oCacheFolder);
}
}
@ -1329,12 +1329,12 @@
}
Events.sub('interval.2m', function () {
self.folderInformation('INBOX');
self.folderInformation(Cache.getFolderInboxName());
});
Events.sub('interval.2m', function () {
var sF = Data.currentFolderFullNameRaw();
if ('INBOX' !== sF)
if (Cache.getFolderInboxName() !== sF)
{
self.folderInformation(sF);
}

View file

@ -143,11 +143,13 @@
};
/**
* @param {string} sInboxFolderName = 'INBOX'
* @return {string}
*/
Links.prototype.inbox = function ()
Links.prototype.inbox = function (sInboxFolderName)
{
return this.sBase + 'mailbox/INBOX';
sInboxFolderName = Utils.isUnd(sInboxFolderName) ? 'INBOX' : sInboxFolderName;
return this.sBase + 'mailbox/' + sInboxFolderName;
};
/**

View file

@ -12,6 +12,8 @@
Utils = require('Common/Utils'),
Events = require('Common/Events'),
Cache = require('Storage/App/Cache'),
AbstractModel = require('Knoin/AbstractModel')
;
@ -71,6 +73,8 @@
*/
FolderModel.prototype.initComputed = function ()
{
var sInboxFolderName = Cache.getFolderInboxName();
this.hasSubScribedSubfolders = ko.computed(function () {
return !!_.find(this.subFolders(), function (oFolder) {
return oFolder.subScribed() && !oFolder.isSystemFolder();
@ -165,11 +169,11 @@
var
bSystem = this.isSystemFolder()
;
return !bSystem && 0 === this.subFolders().length && 'INBOX' !== this.fullNameRaw;
return !bSystem && 0 === this.subFolders().length && sInboxFolderName !== this.fullNameRaw;
}, this);
this.canBeSubScribed = ko.computed(function () {
return !this.isSystemFolder() && this.selectable && 'INBOX' !== this.fullNameRaw;
return !this.isSystemFolder() && this.selectable && sInboxFolderName !== this.fullNameRaw;
}, this);
// this.visible.subscribe(function () {
@ -325,7 +329,11 @@
*/
FolderModel.prototype.initByJson = function (oJsonFolder)
{
var bResult = false;
var
bResult = false,
sInboxFolderName = Cache.getFolderInboxName()
;
if (oJsonFolder && 'Object/Folder' === oJsonFolder['@Object'])
{
this.name(oJsonFolder.Name);
@ -338,7 +346,7 @@
this.existen = !!oJsonFolder.IsExists;
this.subScribed(!!oJsonFolder.IsSubscribed);
this.type('INBOX' === this.fullNameRaw ? Enums.FolderType.Inbox : Enums.FolderType.User);
this.type(sInboxFolderName === this.fullNameRaw ? Enums.FolderType.Inbox : Enums.FolderType.User);
bResult = true;
}

View file

@ -102,6 +102,7 @@
MailBoxAppScreen.prototype.onStart = function ()
{
var
sInboxFolderName = Cache.getFolderInboxName(),
fResizeFunction = function () {
Utils.windowResize();
}
@ -113,9 +114,9 @@
}
_.delay(function () {
if ('INBOX' !== Data.currentFolderFullNameRaw())
if (sInboxFolderName !== Data.currentFolderFullNameRaw())
{
require('App/App').folderInformation('INBOX');
require('App/App').folderInformation(sInboxFolderName);
}
}, 1000);
@ -152,8 +153,9 @@
MailBoxAppScreen.prototype.routes = function ()
{
var
sInboxFolderName = Cache.getFolderInboxName(),
fNormP = function () {
return ['INBOX', 1, '', true];
return [sInboxFolderName, 1, '', true];
},
fNormS = function (oRequest, oVals) {
oVals[0] = Utils.pString(oVals[0]);
@ -163,7 +165,7 @@
if ('' === oRequest)
{
oVals[0] = 'INBOX';
oVals[0] = sInboxFolderName;
oVals[1] = 1;
}
@ -175,7 +177,7 @@
if ('' === oRequest)
{
oVals[0] = 'INBOX';
oVals[0] = sInboxFolderName;
}
return [decodeURI(oVals[0]), 1, decodeURI(oVals[1]), false];

View file

@ -162,6 +162,19 @@
this.oNewMessage = {};
};
/**
* @type {string}
*/
CacheAppStorage.prototype.sInboxFolderName = '';
/**
* @return {string}
*/
CacheAppStorage.prototype.getFolderInboxName = function ()
{
return '' === this.sInboxFolderName ? 'INBOX' : this.sInboxFolderName;
};
/**
* @param {string} sFolderHash
* @return {string}
@ -178,6 +191,10 @@
CacheAppStorage.prototype.setFolderFullNameRaw = function (sFolderHash, sFolderFullNameRaw)
{
this.oFoldersNamesCache[sFolderHash] = sFolderFullNameRaw;
if ('INBOX' === sFolderFullNameRaw || '' === this.sInboxFolderName)
{
this.sInboxFolderName = sFolderFullNameRaw;
}
};
/**

View file

@ -187,7 +187,7 @@
this.folderListSystemNames = ko.computed(function () {
var
aList = ['INBOX'],
aList = [Cache.getFolderInboxName()],
aFolders = this.folderList(),
sSentFolder = this.sentFolder(),
sDraftFolder = this.draftFolder(),
@ -531,7 +531,7 @@
DataAppStorage.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages)
{
if ('INBOX' === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
if (Cache.getFolderInboxName() === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
{
if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
{
@ -632,8 +632,9 @@
iTimeout = iUtc - 60 * 5,
aTimeouts = [],
fSearchFunction = function (aList) {
var sInboxFolderName = Cache.getFolderInboxName();
_.each(aList, function (oFolder) {
if (oFolder && 'INBOX' !== oFolder.fullNameRaw &&
if (oFolder && sInboxFolderName !== oFolder.fullNameRaw &&
oFolder.selectable && oFolder.existen &&
iTimeout > oFolder.interval &&
(!bBoot || oFolder.subScribed()))

View file

@ -251,7 +251,7 @@
sSearch,
Data.projectHash(),
sFolderHash,
'INBOX' === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
Data.threading() && Data.useThreads() ? '1' : '0',
Data.threading() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : ''
].join(String.fromCharCode(0))), bSilent ? [] : ['MessageList']);
@ -263,7 +263,7 @@
'Offset': iOffset,
'Limit': iLimit,
'Search': sSearch,
'UidNext': 'INBOX' === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
'UseThreads': Data.threading() && Data.useThreads() ? '1' : '0',
'ExpandedThreadUid': Data.threading() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : ''
}, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout, '', bSilent ? [] : ['MessageList']);
@ -375,7 +375,7 @@
this.defaultRequest(fCallback, 'FolderInformation', {
'Folder': sFolder,
'FlagsUids': Utils.isArray(aUids) ? aUids.join(',') : '',
'UidNext': 'INBOX' === sFolder ? Cache.getFolderUidNext(sFolder) : ''
'UidNext': Cache.getFolderInboxName() === sFolder ? Cache.getFolderUidNext(sFolder) : ''
});
}
else if (Data.useThreads())

View file

@ -9,6 +9,8 @@
Globals = require('Common/Globals'),
Links = require('Common/Links'),
Cache = require('Storage/App/Cache'),
kn = require('Knoin/Knoin'),
AbstractView = require('Knoin/AbstractView')
;
@ -40,7 +42,7 @@
MenuSettingsAppView.prototype.backToMailBoxClick = function ()
{
kn.setHash(Links.inbox());
kn.setHash(Links.inbox(Cache.getFolderInboxName()));
};
module.exports = MenuSettingsAppView;

View file

@ -11,6 +11,7 @@
Links = require('Common/Links'),
Data = require('Storage/App/Data'),
Cache = require('Storage/App/Cache'),
kn = require('Knoin/Knoin'),
AbstractView = require('Knoin/AbstractView')
@ -45,7 +46,7 @@
PaneSettingsAppView.prototype.backToMailBoxClick = function ()
{
kn.setHash(Links.inbox());
kn.setHash(Links.inbox(Cache.getFolderInboxName()));
};
module.exports = PaneSettingsAppView;

View file

@ -2,7 +2,7 @@
"name": "RainLoop",
"title": "RainLoop Webmail",
"version": "1.6.10",
"release": "182",
"release": "184",
"description": "Simple, modern & fast web-based email client",
"homepage": "http://rainloop.net",
"main": "gulpfile.js",

View file

@ -33,4 +33,5 @@ class Charset
const ISO_8859_1 = 'iso-8859-1';
const ISO_8859_8 = 'iso-8859-8';
const ISO_8859_8_I = 'iso-8859-8-i';
const ISO_2022_JP = 'iso-2022-jp';
}

View file

@ -198,6 +198,27 @@ class Utils
return $sEncoding;
}
/**
* @param string $sCharset
* @param string $sValue
*
* @return string
*/
public static function NormalizeCharsetByValue($sCharset, $sValue)
{
$sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
if (\MailSo\Base\Enumerations\Charset::UTF_8 !== $sCharset &&
\MailSo\Base\Utils::IsUtf8($sValue) &&
false === \strpos($sCharset, \MailSo\Base\Enumerations\Charset::ISO_2022_JP)
)
{
$sCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
}
return $sCharset;
}
/**
* @return bool
*/
@ -296,14 +317,13 @@ class Utils
$mResult = @\iconv(\strtoupper($sInputFromEncoding), \strtoupper($sInputToEncoding).$sIconvOptions, $sInputString);
if (false === $mResult)
{
if (\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger)
if (\MailSo\Log\Logger::IsSystemEnabled())
{
$sHex = 500 < \strlen($sInputString) ? '' : \bin2hex($sInputString);
\MailSo\Config::$SystemLogger->WriteDump(array(
\MailSo\Log\Logger::SystemLog(array(
'inc' => \strtoupper($sInputFromEncoding),
'out' => \strtoupper($sInputToEncoding).$sIconvOptions,
'val' => $sInputString,
'hex' => $sHex
'val' => 500 < \strlen($sInputString) ? \substr($sInputString, 0, 500) : $sInputString,
'hex' => 500 < \strlen($sInputString) ? '-- to long --' : \bin2hex($sInputString)
), \MailSo\Log\Enumerations\Type::NOTICE);
}
@ -471,7 +491,7 @@ class Utils
*/
public static function IsUtf8($sValue)
{
return (bool) (\function_exists('mb_check_encoding') ?
return (bool) ( \function_exists('mb_check_encoding') ?
\mb_check_encoding($sValue, 'UTF-8') : \preg_match('//u', $sValue));
}
@ -527,10 +547,7 @@ class Utils
$sValue = $sEncodedValue;
if (0 < \strlen($sIncomingCharset))
{
if (\MailSo\Base\Enumerations\Charset::UTF_8 !== $sIncomingCharset && \MailSo\Base\Utils::IsUtf8($sValue))
{
$sIncomingCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
}
$sIncomingCharset = \MailSo\Base\Utils::NormalizeCharsetByValue($sIncomingCharset, $sValue);
$sValue = \MailSo\Base\Utils::ConvertEncoding($sValue, $sIncomingCharset,
\MailSo\Base\Enumerations\Charset::UTF_8);
@ -620,10 +637,7 @@ class Utils
}
else
{
if (\MailSo\Base\Enumerations\Charset::UTF_8 !== $aParts[$iIndex][2] && \MailSo\Base\Utils::IsUtf8($aParts[$iIndex][1]))
{
$aParts[$iIndex][2] = \MailSo\Base\Enumerations\Charset::UTF_8;
}
$aParts[$iIndex][2] = \MailSo\Base\Utils::NormalizeCharsetByValue($aParts[$iIndex][2], $aParts[$iIndex][1]);
$sValue = \str_replace($aParts[$iIndex][0],
\MailSo\Base\Utils::ConvertEncoding($aParts[$iIndex][1], $aParts[$iIndex][2], \MailSo\Base\Enumerations\Charset::UTF_8),
@ -633,11 +647,7 @@ class Utils
if ($bOneCharset && 0 < \strlen($sMainCharset))
{
if (\MailSo\Base\Enumerations\Charset::UTF_8 !== $sMainCharset && \MailSo\Base\Utils::IsUtf8($sValue))
{
$sMainCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
}
$sMainCharset = \MailSo\Base\Utils::NormalizeCharsetByValue($sMainCharset, $sValue);
$sValue = \MailSo\Base\Utils::ConvertEncoding($sValue, $sMainCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
}
@ -1163,12 +1173,17 @@ class Utils
$sResult = @\json_encode($mInput, $iOpt);
if (!\is_string($sResult) || '' === $sResult)
{
if (!$oLogger && \MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger)
if (!$oLogger && \MailSo\Log\Logger::IsSystemEnabled())
{
$oLogger = \MailSo\Config::$SystemLogger;
}
if ($oLogger instanceof \MailSo\Log\Logger)
if (!($oLogger instanceof \MailSo\Log\Logger))
{
$oLogger = null;
}
if ($oLogger)
{
$oLogger->Write('json_encode: '.\trim(
(\MailSo\Base\Utils::FunctionExistsAndEnabled('json_last_error') ? ' [Error Code: '.\json_last_error().']' : '').
@ -1179,7 +1194,7 @@ class Utils
if (\is_array($mInput))
{
if ($oLogger instanceof \MailSo\Log\Logger)
if ($oLogger)
{
$oLogger->WriteDump($mInput, \MailSo\Log\Enumerations\Type::INFO, 'JSON');
$oLogger->Write('Trying to clear Utf8 before json_encode', \MailSo\Log\Enumerations\Type::INFO, 'JSON');

View file

@ -83,6 +83,26 @@ class Logger extends \MailSo\Base\Collection
return $oInstance;
}
/**
* @return bool
*/
public static function IsSystemEnabled()
{
return !!(\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger);
}
/**
* @param mixed $mData
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
*/
public static function SystemLog($mData, $iType = \MailSo\Log\Enumerations\Type::INFO)
{
if (\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger)
{
\MailSo\Config::$SystemLogger->WriteMixed($mData, $iType);
}
}
/**
* @staticvar string $sCache;
*

View file

@ -279,6 +279,9 @@ abstract class NetClient
\restore_error_handler();
$this->writeLog('Connected ('.(\is_resource($this->rConnect) ? 'success' : 'unsuccess').')',
\MailSo\Log\Enumerations\Type::NOTE);
if (!\is_resource($this->rConnect))
{
$this->writeLogException(
@ -316,7 +319,7 @@ abstract class NetClient
}
}
}
/**
* @return void
*/

View file

@ -676,13 +676,13 @@ class Actions
case ('APC' === $sDriver || 'APCU' === $sDriver) &&
\MailSo\Base\Utils::FunctionExistsAndEnabled(array(
'apc_store', 'apc_fetch', 'apc_delete', 'apc_clear_cache')):
$oDriver = \MailSo\Cache\Drivers\APC::NewInstance();
break;
case ('MEMCACHE' === $sDriver || 'MEMCACHED' === $sDriver) &&
\MailSo\Base\Utils::FunctionExistsAndEnabled('memcache_connect'):
$oDriver = \MailSo\Cache\Drivers\Memcache::NewInstance(
$this->Config()->Get('labs', 'fast_cache_memcache_host', '127.0.0.1'),
(int) $this->Config()->Get('labs', 'fast_cache_memcache_port', 11211)
@ -755,11 +755,11 @@ class Actions
$this->oLogger->WriteEmptyLine();
$oHttp = $this->Http();
$this->oLogger->Write('[DATE:'.\gmdate('d.m.y').'][RL:'.APP_VERSION.'][PHP:'.PHP_VERSION.'][IP:'.
$oHttp->GetClientIp().'][PID:'.(\MailSo\Base\Utils::FunctionExistsAndEnabled('getmypid') ? \getmypid() : 'unknown').
'][GUID:'.\MailSo\Log\Logger::Guid().']');
$this->oLogger->Write(
'[APC:'.(\MailSo\Base\Utils::FunctionExistsAndEnabled('apc_fetch') ? 'on' : 'off').']'.
'[MB:'.(\MailSo\Base\Utils::FunctionExistsAndEnabled('mb_convert_encoding') ? 'on' : 'off').']'.
@ -901,7 +901,7 @@ class Actions
$oAccount->SetProxyAuthUser($aAccountHash[8]);
$oAccount->SetProxyAuthUser($aAccountHash[89]);
}
$this->Logger()->AddSecret($oAccount->Password());
$this->Logger()->AddSecret($oAccount->ProxyAuthPassword());
@ -1489,7 +1489,7 @@ class Actions
if (false === \strpos($sEmail, '@') || 0 === \strlen($sPassword))
{
$this->loginErrorDelay();
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidInputArgument);
}
@ -1501,7 +1501,7 @@ class Actions
$this->Logger()->AddSecret($sPassword);
$this->Plugins()->RunHook('event.login-pre-login-provide', array());
try
{
$oAccount = $this->LoginProvide($sEmail, $sLogin, $sPassword, $sSignMeToken, true);
@ -1540,7 +1540,7 @@ class Actions
if (empty($sAdditionalCode))
{
$this->Logger()->Write('TFA: Required Code for '.$oAccount->ParentEmailHelper().' account.');
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AccountTwoFactorAuthRequired);
}
else
@ -4747,7 +4747,7 @@ class Actions
{
$oSmtpClient->Logout();
}
$oSmtpClient->Disconnect();
}
}