From b15fe723595219e0e31ec84af246446668d297c8 Mon Sep 17 00:00:00 2001 From: Gareth Aye Date: Tue, 8 Apr 2014 20:39:18 -0400 Subject: Bug 974554 - CalDAV parser should accept ical inside xml comments nested in elements --- caldav.js | 25 +++++++++++--- lib/caldav/sax.js | 5 +++ lib/caldav/sax/calendar_data_handler.js | 17 ++++++--- test/caldav/sax/calendar_data_handler_test.js | 50 +++++++++++++++------------ test/caldav/sax_test.js | 20 +++++++++-- 5 files changed, 83 insertions(+), 34 deletions(-) diff --git a/caldav.js b/caldav.js index 6f43d34..0f21ea6 100644 --- a/caldav.js +++ b/caldav.js @@ -1463,6 +1463,7 @@ function write (chunk) { var events = [ 'ontext', + 'oncdata', 'onopentag', 'onclosetag', 'onerror', @@ -1643,6 +1644,10 @@ function write (chunk) { this._fireHandler('ontext', data); }, + oncdata: function(data) { + this._fireHandler('oncdata', data); + }, + onerror: function(data) { //TODO: XXX implement handling of parsing errors. //unlikely but possible if server goes down @@ -2739,7 +2744,8 @@ function write (chunk) { (function(module, ns) { - var XHR = ns.require('xhr'); + var Caldav = ns.require('caldav'), + XHR = ns.require('xhr'); /** * Connection objects contain @@ -2941,12 +2947,21 @@ function write (chunk) { //value where key is local tag name //and value is the text. ontext: function(data) { - var handler = this.handler; - this.current[this.currentTag[handler.tagField]] = - CalendarDataHandler.parseICAL(data); - } + return CalendarDataHandler.ondata.call(this, data); + }, + + // Servers can also stash ical data inside of an xml cdata. + oncdata: function(data) { + return CalendarDataHandler.ondata.call(this, data); + }, }); + CalendarDataHandler.ondata = function(data) { + var handler = this.handler; + this.current[this.currentTag[handler.tagField]] = + CalendarDataHandler.parseICAL(data); + }; + /** * Default ical parser handler. * diff --git a/lib/caldav/sax.js b/lib/caldav/sax.js index e0c0a1b..c861eee 100644 --- a/lib/caldav/sax.js +++ b/lib/caldav/sax.js @@ -18,6 +18,7 @@ var events = [ 'ontext', + 'oncdata', 'onopentag', 'onclosetag', 'onerror', @@ -198,6 +199,10 @@ this._fireHandler('ontext', data); }, + oncdata: function(data) { + this._fireHandler('oncdata', data); + }, + onerror: function(data) { //TODO: XXX implement handling of parsing errors. //unlikely but possible if server goes down diff --git a/lib/caldav/sax/calendar_data_handler.js b/lib/caldav/sax/calendar_data_handler.js index d24bfb0..ac55c78 100644 --- a/lib/caldav/sax/calendar_data_handler.js +++ b/lib/caldav/sax/calendar_data_handler.js @@ -14,12 +14,21 @@ //value where key is local tag name //and value is the text. ontext: function(data) { - var handler = this.handler; - this.current[this.currentTag[handler.tagField]] = - CalendarDataHandler.parseICAL(data); - } + return CalendarDataHandler.ondata.call(this, data); + }, + + // Servers can also stash ical data inside of an xml cdata. + oncdata: function(data) { + return CalendarDataHandler.ondata.call(this, data); + }, }); + CalendarDataHandler.ondata = function(data) { + var handler = this.handler; + this.current[this.currentTag[handler.tagField]] = + CalendarDataHandler.parseICAL(data); + }; + /** * Default ical parser handler. * diff --git a/test/caldav/sax/calendar_data_handler_test.js b/test/caldav/sax/calendar_data_handler_test.js index 867cbe3..9f33192 100644 --- a/test/caldav/sax/calendar_data_handler_test.js +++ b/test/caldav/sax/calendar_data_handler_test.js @@ -34,33 +34,39 @@ suite('caldav/sax/calendar_data_handler', function() { }; }); - suite('ontext', function() { - var originalHandler; + // Should treat text and xml character data the same. + [ + 'ontext', + 'oncdata' + ].forEach(function(nodetype) { + suite(nodetype, function() { + var originalHandler; - suiteSetup(function() { - originalHandler = Handler.parseICAL; - }); + suiteSetup(function() { + originalHandler = Handler.parseICAL; + }); - teardown(function() { - Handler.parseICAL = originalHandler; - }); + teardown(function() { + Handler.parseICAL = originalHandler; + }); - test('without handler', function() { - callProxy('ontext', 'foo'); - assert.equal(proxy.current[0], 'foo'); - }); - test('with handler', function() { - var calledWith; - Handler.parseICAL = function() { - calledWith = arguments; - return 'hit'; - } + test('without handler', function() { + callProxy(nodetype, 'foo'); + assert.equal(proxy.current[0], 'foo'); + }); - callProxy('ontext', 'baz'); - assert.deepEqual(calledWith, ['baz']); - assert.equal(proxy.current[0], 'hit'); + test('with handler', function() { + var calledWith; + Handler.parseICAL = function() { + calledWith = arguments; + return 'hit'; + }; + + callProxy(nodetype, 'baz'); + assert.deepEqual(calledWith, ['baz']); + assert.equal(proxy.current[0], 'hit'); + }); }); }); }); - diff --git a/test/caldav/sax_test.js b/test/caldav/sax_test.js index 8896abf..a175cdd 100644 --- a/test/caldav/sax_test.js +++ b/test/caldav/sax_test.js @@ -15,6 +15,7 @@ suite('caldav/sax', function() { // to make testing easier. function TestHander() { this.text = []; + this.cdata = []; this.opentag = []; this.closetag = []; this.error = []; @@ -22,9 +23,13 @@ suite('caldav/sax', function() { this.end = []; var events = [ - 'ontext', 'onclosetag', - 'onopentag', 'onerror', - 'oncomplete', 'onend' + 'ontext', + 'oncdata', + 'onclosetag', + 'onopentag', + 'onerror', + 'oncomplete', + 'onend' ]; } @@ -34,6 +39,10 @@ suite('caldav/sax', function() { handler.text.push(data); }, + oncdata: function(data, handler) { + handler.cdata.push(data); + }, + onclosetag: function(data, handler) { handler.closetag.push(data); }, @@ -237,6 +246,11 @@ suite('caldav/sax', function() { firesHandler('text', 'foo'); }); + test('#oncdata', function() { + subject.oncdata('foo'); + firesHandler('cdata', 'foo'); + }); + test('#onerror', function() { subject.onerror('foo'); firesHandler('error', 'foo'); -- cgit