Bug 816028 - Workaround for zimbra server crash on LIST (SUBSCRIBED). r=irving

This commit is contained in:
David Lechner 2012-12-20 21:11:08 -06:00
Родитель 71d1695291
Коммит 190f70f2a7
6 изменённых файлов: 106 добавлений и 48 удалений

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
#include "nsIStringBundle.h"
#include "nsVersionComparator.h"
#include "nsMsgImapCID.h"
#include "nsThreadUtils.h"
@ -7566,6 +7567,26 @@ nsCString nsImapProtocol::CreatePossibleTrashName(const char *prefix)
return returnTrash;
}
bool nsImapProtocol::GetListSubscribedIsBrokenOnServer()
{
// This is a workaround for an issue with LIST(SUBSCRIBED) crashing older versions of Zimbra
if (GetServerStateParser().GetServerID().Find("\"NAME\" \"Zimbra\"", CaseInsensitiveCompare) != kNotFound) {
nsCString serverID(GetServerStateParser().GetServerID());
int start = serverID.Find("\"VERSION\" \"", CaseInsensitiveCompare) + 11;
int length = serverID.Find("\" ", start, CaseInsensitiveCompare);
const nsDependentCSubstring serverVersionSubstring = Substring(serverID, start, length);
nsCString serverVersionStr(serverVersionSubstring);
Version serverVersion(serverVersionStr.get());
Version sevenTwoThree("7.2.3_");
Version eightZeroZero("8.0.0_");
Version eightZeroThree("8.0.3_");
if ((serverVersion < sevenTwoThree) ||
((serverVersion >= eightZeroZero) && (serverVersion < eightZeroThree)))
return true;
}
return false;
}
void nsImapProtocol::Lsub(const char *mailboxPattern, bool addDirectoryIfNecessary)
{
ProgressEventFunctionUsingId (IMAP_STATUS_LOOKING_FOR_MAILBOX);
@ -7582,7 +7603,8 @@ void nsImapProtocol::Lsub(const char *mailboxPattern, bool addDirectoryIfNecessa
mailboxPattern, escapedPattern);
nsCString command (GetServerCommandTag());
if (GetServerStateParser().GetCapabilityFlag() & kHasListExtendedCapability)
if ((GetServerStateParser().GetCapabilityFlag() & kHasListExtendedCapability) &&
!GetListSubscribedIsBrokenOnServer())
command += " list (subscribed)";
else
command += " lsub";

Просмотреть файл

@ -389,7 +389,7 @@ private:
// biff
void PeriodicBiff();
void SendSetBiffIndicatorEvent(nsMsgBiffState newState);
bool CheckNewMail();
bool CheckNewMail();
// folder opening and listing header functions
void FolderHeaderDump(uint32_t *msgUids, uint32_t msgCount);
@ -534,6 +534,9 @@ private:
void DiscoverAllAndSubscribedBoxes();
void MailboxDiscoveryFinished();
void NthLevelChildList(const char *onlineMailboxPrefix, int32_t depth);
// LIST SUBSCRIBED command (from RFC 5258) crashes some servers. so we need to
// identify those servers
bool GetListSubscribedIsBrokenOnServer();
void Lsub(const char *mailboxPattern, bool addDirectoryIfNecessary);
void List(const char *mailboxPattern, bool addDirectoryIfNecessary,
bool useXLIST = false);

Просмотреть файл

@ -12,39 +12,6 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const kIDResponse = "(\"name\" \"GImap\" \"vendor\" \"Google, Inc.\" \"support-url\" \"http://mail.google.com/support\")";
const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
const XULAPPINFO_CID = Components.ID("{7e10a36e-1085-4302-9e3f-9571fc003ee0}");
var gAppInfo = null;
function createAppInfo(id, name, version, platformVersion) {
gAppInfo = {
// nsIXULAppInfo
vendor: "Mozilla",
name: name,
ID: id,
version: version,
appBuildID: "2007010101",
platformVersion: platformVersion,
platformBuildID: "2007010101",
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIXULAppInfo,
Components.interfaces.nsISupports])
};
var XULAppInfoFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return gAppInfo.QueryInterface(iid);
}
};
var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
XULAPPINFO_CONTRACTID, XULAppInfoFactory);
}
var tests = [
setup,
function updateInbox() {
@ -60,8 +27,6 @@ var tests = [
]
function setup() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "5", "2.0");
setupIMAPPump("GMail");
gIMAPDaemon.idResponse = kIDResponse;

Просмотреть файл

@ -2,10 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Test that listing subscribed mailboxes uses LIST (SUBSCRIBED) instead of LSUB
// for servers that have LIST-EXTENDED capability
// see: bug 495318
// see: RFC 5258 - http://tools.ietf.org/html/rfc5258
/** Test that listing subscribed mailboxes uses LIST (SUBSCRIBED) instead of LSUB
* for servers that have LIST-EXTENDED capability
*/
/* References:
* RFC 5258 - http://tools.ietf.org/html/rfc5258
* Bug 495318
* Bug 816028
* http://bugzilla.zimbra.com/show_bug.cgi?id=78794
*/
// async support
load("../../../resources/logHelper.js");
@ -19,15 +24,17 @@ load("../../../resources/IMAPpump.js");
Components.utils.import("resource://gre/modules/Services.jsm");
// Globals
let nsMsgFolderFlags = Ci.nsMsgFolderFlags;
// Dovecot is one of the servers that supports LIST-EXTENDED
setupIMAPPump("Dovecot");
// Zimbra is one of the servers that supports LIST-EXTENDED
// it also has a bug that causes a server crash in certain setups
setupIMAPPump("Zimbra");
// Definition of tests
var tests = [
setupMailboxes,
testListSubscribed,
testZimbraServerVersions,
endTest
]
@ -48,8 +55,6 @@ function setupMailboxes()
// tests that LIST (SUBSCRIBED) returns the proper response
function testListSubscribed()
{
let nsMsgFolderFlags = Ci.nsMsgFolderFlags;
// check that we have \Noselect and \Noinferiors flags - these would not have
// been returned if we had used LSUB instead of LIST(SUBSCRIBED)
let rootFolder = gIMAPIncomingServer.rootFolder;
@ -77,6 +82,35 @@ function testListSubscribed()
yield true;
}
function testZimbraServerVersions() {
// older versions of Zimbra can crash if we send LIST (SUBSCRIBED) so we want
// to make sure that we are checking for versions
let testValues = [ { version : '6.3.1_GA_2790', expectedResult : false },
{ version : '7.2.2_GA_2790', expectedResult : false },
{ version : '7.2.3_GA_2790', expectedResult : true },
{ version : '8.0.2_GA_2790', expectedResult : false },
{ version : '8.0.3_GA_2790', expectedResult : true },
{ version : '9.0.0_GA_2790', expectedResult : true } ];
for (let i = 0; i < testValues.length; i++) {
gIMAPDaemon.idResponse = '("NAME" "Zimbra" ' +
'"VERSION" "' + testValues[i].version + '" ' +
'"RELEASE" "20120815212257" ' +
'"USER" "user@domain.com" ' +
'"SERVER" "14b63305-d002-4f1b-bcd9-23d402d4ef40")';
gIMAPIncomingServer.closeCachedConnections();
gIMAPIncomingServer.performExpand(null);
// select inbox is just to wait on performExpand since performExpand does not have listener
gIMAPInbox.updateFolderWithListener(null, asyncUrlListener);
yield false;
// if we send LSUB instead of LIST(SUBSCRIBED), then we should not have \NoSelect flag
let rootFolder = gIMAPIncomingServer.rootFolder;
let folder1 = rootFolder.getChildNamed("folder1");
do_check_eq(folder1.getFlag(nsMsgFolderFlags.ImapNoselect), testValues[i].expectedResult);
}
}
// Cleanup at end
function endTest()
{

Просмотреть файл

@ -1699,7 +1699,7 @@ var configurations = {
Cyrus: ["RFC2342", "RFC2195", "RFC5258"],
UW: ["RFC2342", "RFC2195"],
Dovecot: ["RFC2195", "RFC5258"],
Zimbra: ["RFC2342", "RFC2195", "RFC5258"],
Zimbra: ["RFC2197", "RFC2342", "RFC2195", "RFC5258"],
Exchange: ["RFC2342", "RFC2195"],
LEMONADE: ["RFC2342", "RFC2195"],
CUSTOM1: ["MOVE", "RFC4315", "CUSTOM"],
@ -1970,7 +1970,7 @@ var IMAP_CUSTOM_extension = {
// RFC 2197: ID
var IMAP_RFC2197_extension = {
ID: function (args) {
ID : function (args) {
let clientID = "(";
for each (let i in args)
clientID += "\"" + i + "\"";

Просмотреть файл

@ -38,9 +38,11 @@ var gIMAPServer; // the imap fake server
var gIMAPIncomingServer; // nsIMsgIncomingServer for the imap server
var gIMAPInbox; // nsIMsgFolder/nsIMsgImapMailFolder for imap inbox
var gIMAPMailbox; // imap fake server mailbox
var gAppInfo; // application info
function setupIMAPPump(extensions)
{
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "5", "2.0");
// These are copied from imap's head_server.js to here so we can run
// this from any directory.
@ -132,4 +134,36 @@ function teardownIMAPPump()
thread.processNextEvent(true);
}
const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
const XULAPPINFO_CID = Components.ID("{7e10a36e-1085-4302-9e3f-9571fc003ee0}");
function createAppInfo(id, name, version, platformVersion) {
gAppInfo = {
// nsIXULAppInfo
vendor: "Mozilla",
name: name,
ID: id,
version: version,
appBuildID: "2007010101",
platformVersion: platformVersion,
platformBuildID: "2007010101",
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIXULAppInfo,
Components.interfaces.nsISupports])
};
var XULAppInfoFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return gAppInfo.QueryInterface(iid);
}
};
var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
XULAPPINFO_CONTRACTID, XULAppInfoFactory);
}
} // end run only once