From 297f7c493f83e2c04dd2ec266880d41252679d32 Mon Sep 17 00:00:00 2001 From: Felix Hammerl Date: Tue, 30 Sep 2014 12:30:08 +0200 Subject: [PATCH] [WO-625] Catch exception on socket.oncert Mozilla's socket is not extensible via Object.preventExtensions(obj) and throws exceptions when non-prototype function .oncert is added. The callback function is needed for the other shims. --- src/js/util/connection-doctor.js | 18 ++++++++++++------ test/unit/connection-doctor-test.js | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/js/util/connection-doctor.js b/src/js/util/connection-doctor.js index 6903844..43e047a 100644 --- a/src/js/util/connection-doctor.js +++ b/src/js/util/connection-doctor.js @@ -162,12 +162,18 @@ define(function(require) { socket.ondata = function() {}; // we don't actually care about the data - socket.oncert = function() { - if (options.ca) { - // the certificate we already have is outdated - error = createError(TLS_WRONG_CERT, strings.connDocTlsWrongCert.replace('{0}', host)); - } - }; + // [WO-625] Mozilla forbids extensions to the TCPSocket object, + // throws an exception when assigned unexpected callback functions. + // The exception can be safely ignored since we need the callback + // for the other shims + try { + socket.oncert = function() { + if (options.ca) { + // the certificate we already have is outdated + error = createError(TLS_WRONG_CERT, strings.connDocTlsWrongCert.replace('{0}', host)); + } + }; + } catch (e) {} socket.onerror = function(e) { if (!error) { diff --git a/test/unit/connection-doctor-test.js b/test/unit/connection-doctor-test.js index 97f2ed9..1ffeb08 100644 --- a/test/unit/connection-doctor-test.js +++ b/test/unit/connection-doctor-test.js @@ -23,6 +23,7 @@ define(function(require) { this.onclose(); } }; + imapStub = sinon.createStubInstance(ImapClient); smtpStub = sinon.createStubInstance(SmtpClient); @@ -95,6 +96,29 @@ define(function(require) { socketStub.onopen(); }); + it('should catch Mozilla TCPSocket exception', function(done) { + // Mozilla forbids extensions to the TCPSocket object + Object.defineProperty(socketStub, 'oncert', { + set: function() { + throw 'Mozilla specific behavior'; + } + }); + + doctor._checkReachable(credentials.imap, function(error) { + expect(error).to.not.exist; + expect(TCPSocket.open.calledOnce).to.be.true; + expect(TCPSocket.open.calledWith(credentials.imap.host, credentials.imap.port, { + binaryType: 'arraybuffer', + useSecureTransport: credentials.imap.secure, + ca: credentials.imap.ca + })).to.be.true; + + done(); + }); + + socketStub.onopen(); + }); + it('should fail w/ wrong cert', function(done) { doctor._checkReachable(credentials.imap, function(error) { expect(error).to.exist;