diff --git a/api/js/jsapi/egw_utils.js b/api/js/jsapi/egw_utils.js index 1c8c97ab2b..21b426e4b1 100644 --- a/api/js/jsapi/egw_utils.js +++ b/api/js/jsapi/egw_utils.js @@ -204,6 +204,20 @@ egw.extend('utils', egw.MODULE_GLOBAL, function() return _comp.replace(/#/g,'%23').replace(/\?/g,'%3F').replace(/\//g,''); }, + /** + * Escape HTML special chars, just like PHP + * + * @param {string} s String to encode + * + * @return {string} + */ + htmlspecialchars: function(s) { + return s.replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>'); + }, + /** * If an element has display: none (or a parent like that), it has no size. * Use this to get its dimensions anyway. diff --git a/calendar/js/et2_widget_event.js b/calendar/js/et2_widget_event.js index d9559dfc15..163bd908ba 100644 --- a/calendar/js/et2_widget_event.js +++ b/calendar/js/et2_widget_event.js @@ -321,7 +321,7 @@ var et2_calendar_event = (function(){ "use strict"; return et2_valueWidget.exten this.body.toggleClass('calendar_calEventBodySmall', event.whole_day_on_top || false); // Header - var title = !event.is_private ? event['title'] : egw.lang('private'); + var title = !event.is_private ? egw.htmlspecialchars(event['title']) : egw.lang('private'); this.title .html(''+this._get_timespan(event) + '
') @@ -361,7 +361,7 @@ var et2_calendar_event = (function(){ "use strict"; return et2_valueWidget.exten if(this.options.value.description.trim()) { this.body - .append('

'+this.options.value.description+'

'); + .append('

'+egw.htmlspecialchars(this.options.value.description)+'

'); } } @@ -517,10 +517,11 @@ var et2_calendar_event = (function(){ "use strict"; return et2_valueWidget.exten ''+ '
'+ '

'+ - ''+this.options.value.title+'
'+ - this.options.value.description+'

'+ + ''+egw.htmlspecialchars(this.options.value.title)+'
'+ + egw.htmlspecialchars(this.options.value.description)+'

'+ '

'+times+'

'+ - (this.options.value.location ? '

'+this.egw().lang('Location') + ':' + this.options.value.location+'

' : '')+ + (this.options.value.location ? '

'+this.egw().lang('Location') + ':' + + egw.htmlspecialchars(this.options.value.location)+'

' : '')+ (cat_label ? '

'+this.egw().lang('Category') + ':' + cat_label +'

' : '')+ '

'+this.egw().lang('Participants')+':
'+ participants + '

'+ this._participant_summary(this.options.value.participants) +