From 59584283c52f06a478e61e93b1d0f69a750a1768 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Wed, 17 May 2017 11:13:58 +0200 Subject: [FIX] web: properly escape field values when necessary This rev. removes some html injections issues: - in char and text field widgets - in phone field widget in mobile - in list views (when no widget is instantiated) --- addons/web/static/src/js/fields/basic_fields.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index cafa59bbd00..6f757e5414e 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -240,7 +240,7 @@ var InputField = DebouncedField.extend({ * @private */ _renderReadonly: function () { - this.$el.html(this._formatValue(this.value)); + this.$el.text(this._formatValue(this.value)); }, //-------------------------------------------------------------------------- @@ -523,6 +523,13 @@ var FieldMonetary = InputField.extend({ this.$el.prepend($currencySymbol); } }, + /** + * @override + * @private + */ + _renderReadonly: function () { + this.$el.html(this._formatValue(this.value)); + }, /** * Re-gets the currency as its value may have changed. * @see FieldMonetary.resetOnAnyFieldChange @@ -885,8 +892,11 @@ var FieldPhone = FieldEmail.extend({ _renderReadonly: function () { this._super(); if (this._canCall()) { + // Split phone number into two to prevent Skype app from finding it var text = this.$el.text(); - this.$el.html(text.substr(0, text.length/2) + "­" + text.substr(text.length/2)); // To prevent Skype app to find the phone number + var part1 = _.escape(text.substr(0, text.length/2)); + var part2 = _.escape(text.substr(text.length/2)); + this.$el.html(part1 + "­" + part2); } else { this.$el.removeClass('o_form_uri'); } @@ -1540,7 +1550,7 @@ var FieldPercentPie = AbstractField.extend({ this.$leftMask.css({transform: leftDeg, msTransform: leftDeg, mozTransform: leftDeg, webkitTransform: leftDeg}); this.$rightMask.css({transform: rightDeg, msTransform: rightDeg, mozTransform: rightDeg, webkitTransform: rightDeg}); - this.$pieValue.html(Math.round(value) + '%'); + this.$pieValue.text(Math.round(value) + '%'); }, }); @@ -1681,9 +1691,9 @@ var FieldProgressBar = AbstractField.extend({ if (!this.write_mode) { if (max_value !== 100) { - this.$('.o_progressbar_value').html(utils.human_number(value) + " / " + utils.human_number(max_value)); + this.$('.o_progressbar_value').text(utils.human_number(value) + " / " + utils.human_number(max_value)); } else { - this.$('.o_progressbar_value').html(utils.human_number(value) + "%"); + this.$('.o_progressbar_value').text(utils.human_number(value) + "%"); } } else if (isNaN(v)) { this.$('.o_progressbar_value').val(this.edit_max_value ? max_value : value); -- cgit v1.2.3 From ba6a3a91ae78297c7f8ddcf7630ecef46048c15e Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Wed, 17 May 2017 09:22:40 +0200 Subject: [FIX] web: MonetaryField: read currency_field in options In the xml definition of views, a 'currency_field' can be specified in the node options: It indicates which field the monetary widget has to use to determine the currency to display. Before this rev., the widget didn't look for the 'currency_field' in the options, but directly in the node attrs, so this simply didn't work. This was for example the case on the crm.lead kanban and form views. --- addons/web/static/src/js/fields/basic_fields.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 6f757e5414e..b35b84fe6ee 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -548,7 +548,7 @@ var FieldMonetary = InputField.extend({ * @private */ _setCurrency: function () { - var currencyField = this.attrs.currency_field || this.field.currency_field || 'currency_id'; + var currencyField = this.nodeOptions.currency_field || this.field.currency_field || 'currency_id'; var currencyID = this.record.data[currencyField] && this.record.data[currencyField].res_id; this.currency = session.get_currency(currencyID); }, -- cgit v1.2.3 From c929a81e8f015f9234f68749a29fe6a9c21577b6 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Fri, 19 May 2017 10:13:24 +0200 Subject: [FIX] web: DebounceField: do nothing after widget destruction DebounceFields debounce the function that notify field changes to their environment (using _.debounce). It may happen that this function is called once the field widget is destroyed (e.g. type something in a char field and quickly click on Save, the function is called directly by _commitChanges, but the debounced call is still pending). It may be a problem if the subsequent code does something like this.getSession().some_key, as if the widget is destroyed, it has no parent that can provide it the session, and thus it crashes. Also rename attribute _debouncedStarted into _isDirty as it makes much more sense. --- addons/web/static/src/js/fields/basic_fields.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index b35b84fe6ee..3f279eeeec7 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -83,10 +83,10 @@ var DebouncedField = AbstractField.extend({ init: function () { this._super.apply(this, arguments); - // _debouncedStarted is used to detect that the user interacted at least + // _isDirty is used to detect that the user interacted at least // once with the widget, so that we can prevent it from triggering a // field_changed in commitChanges if the user didn't change anything - this._debouncedStarted = false; + this._isDirty = false; if (this.mode === 'edit') { if (this.DEBOUNCE) { this._doDebouncedAction = _.debounce(this._doAction, this.DEBOUNCE); @@ -97,7 +97,7 @@ var DebouncedField = AbstractField.extend({ var self = this; var debouncedFunction = this._doDebouncedAction; this._doDebouncedAction = function () { - self._debouncedStarted = true; + self._isDirty = true; debouncedFunction.apply(self, arguments); }; } @@ -115,7 +115,7 @@ var DebouncedField = AbstractField.extend({ * @override */ commitChanges: function () { - if (this._debouncedStarted && this.mode === 'edit') { + if (this._isDirty && this.mode === 'edit') { this._doAction(); } }, @@ -132,7 +132,13 @@ var DebouncedField = AbstractField.extend({ * @private */ _doAction: function () { - this._setValue(this._getValue()); + // as _doAction may be debounced, it may happen that it is called after + // the widget has been destroyed, and in this case, we don't want it to + // do anything (commitChanges ensures that if it has local changes, they + // are triggered up before the widget is destroyed, if necessary). + if (!this.isDestroyed()) { + this._setValue(this._getValue()); + } }, /** * Should return the current value of the field, in the DOM (for example, -- cgit v1.2.3 From bbf724e4012e983d56bea27b66caa204294ebda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Mon, 29 May 2017 11:22:26 +0200 Subject: [FIX] web: properly support password attribute for fields With the new views, the special attribute password was no longer supported. We simply reintroduce in this commit proper support to display password fields with *. Note: we may want to display passwords with a static number of *, but this requires some thoughts on the usability of the change. We simply reintroduce the previous behaviour here. --- addons/web/static/src/js/fields/basic_fields.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 3f279eeeec7..cdaed1d7b4f 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -165,6 +165,7 @@ var InputField = DebouncedField.extend({ */ init: function () { this._super.apply(this, arguments); + this.nodeOptions.isPassword = 'password' in this.attrs; if (this.mode === 'edit') { this.tagName = 'input'; } @@ -222,7 +223,7 @@ var InputField = DebouncedField.extend({ this.$input = $input || $(""); this.$input.addClass('o_input'); this.$input.attr({ - type: 'text', + type: this.nodeOptions.isPassword ? 'password' : 'text', placeholder: this.attrs.placeholder || "", }); this.$input.val(this._formatValue(this.value)); -- cgit v1.2.3 From e116a69f25d3d3dcfa9ee12b34c33d9c3658bb46 Mon Sep 17 00:00:00 2001 From: Martin Geubelle Date: Tue, 30 May 2017 11:28:05 +0200 Subject: [FIX] web: properly handle autocomplete attribute With the new views, the attribute autocomplete on input was no longer supported. We simply reintroduce its support in this commit. The basic attribute values are 'on' and 'off' but one may want to use a random string. Note that an input with type='password' is a special case: the autocomplete attribute should always be set to 'new-password' to remove autocompletion (autocomplete='off' doesn't actually remove the autocompletion). --- addons/web/static/src/js/fields/basic_fields.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index cdaed1d7b4f..a5ceba50d3f 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -225,6 +225,9 @@ var InputField = DebouncedField.extend({ this.$input.attr({ type: this.nodeOptions.isPassword ? 'password' : 'text', placeholder: this.attrs.placeholder || "", + autocomplete: this.nodeOptions.isPassword ? + 'new-password' : + this.attrs.autocomplete, }); this.$input.val(this._formatValue(this.value)); return this.$input; -- cgit v1.2.3