[FIX] web: fix evaluation context of the domain selector

The domain was instantiated without being given any evaluation context.
As a result, the uid variable was not defined,
crashing the js if present in a user-defined filter.

opw 1866852
This commit is contained in:
Aaron Bohy
2018-08-30 14:55:06 +02:00
committed by len-odoo
parent 1ece9412be
commit 68332a0177
4 changed files with 58 additions and 18 deletions
@@ -2264,19 +2264,18 @@ var FieldDomain = AbstractField.extend({
// Convert char value to array value
var value = this.value || "[]";
var domain = Domain.prototype.stringToArray(value);
// Create the domain selector or change the value of the current one...
var def;
if (!this.domainSelector) {
this.domainSelector = new DomainSelector(this, this._domainModel, domain, {
this.domainSelector = new DomainSelector(this, this._domainModel, value, {
readonly: this.mode === "readonly" || this.inDialog,
filters: this.fsFilters,
debugMode: session.debug,
});
def = this.domainSelector.prependTo(this.$el);
} else {
def = this.domainSelector.setDomain(domain);
def = this.domainSelector.setDomain(value);
}
// ... then replace the other content (matched records, etc)
return def.then(this._replaceContent.bind(this));
@@ -2429,11 +2429,11 @@ var BasicModel = AbstractModel.extend({
}
var def = $.Deferred();
var evalContext = this._getEvalContext(record);
this._rpc({
model: domainModel,
method: 'search_count',
args: [Domain.prototype.stringToArray(domainValue)],
args: [Domain.prototype.stringToArray(domainValue, evalContext)],
context: context
})
.then(_.identity, function (error, e) {
@@ -177,18 +177,12 @@ var DomainTree = DomainNode.extend({
* operator from the domain.
* @see DomainTree._addFlattenedChildren
*/
init: function (parent, model, domain, options) {
init: function (parent, model, domain) {
this._super.apply(this, arguments);
try {
domain = Domain.prototype.stringToArray(domain);
} catch (err) {
// TODO: domain could contain `parent` for example, which is
// currently not handled by the DomainSelector
this.invalidDomain = true;
this.children = [];
return;
var parsedDomain = this._parseDomain(domain);
if (parsedDomain) {
this._initialize(parsedDomain);
}
this._initialize(domain);
},
/**
* @see DomainNode.start
@@ -386,6 +380,23 @@ var DomainTree = DomainNode.extend({
});
}).bind(this));
},
/**
* @param {string} domain
* @returns {Array[]}
*/
_parseDomain: function (domain) {
var parsedDomain = false;
try {
parsedDomain = Domain.prototype.stringToArray(domain);
this.invalidDomain = false;
} catch (err) {
// TODO: domain could contain `parent` for example, which is
// currently not handled by the DomainSelector
this.invalidDomain = true;
this.children = [];
}
return parsedDomain;
},
//--------------------------------------------------------------------------
// Handlers
@@ -471,14 +482,17 @@ var DomainSelector = DomainTree.extend({
* If the internal domain value was already equal to the given one, this
* does nothing.
*
* @param {Array|string} domain
* @param {string} domain
* @returns {Deferred} resolved when the rerendering is finished
*/
setDomain: function (domain) {
if (Domain.prototype.arrayToString(domain) === Domain.prototype.arrayToString(this.getDomain())) {
if (domain === Domain.prototype.arrayToString(this.getDomain())) {
return $.when();
}
return this._redraw(domain);
var parsedDomain = this._parseDomain(domain);
if (parsedDomain) {
return this._redraw(domain);
}
},
//--------------------------------------------------------------------------
@@ -4345,6 +4345,33 @@ QUnit.module('basic_fields', {
QUnit.module('FieldDomain');
QUnit.test('The domain editor should not crash the view when given a dynamic filter', function (assert) {
//dynamic filters (containing variables, such as uid, parent or today)
//are not handled by the domain editor, but it shouldn't crash the view
assert.expect(1);
this.data.partner.records[0].foo = '[["int_field", "=", uid]]';
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch:
'<form>' +
'<field name="foo" widget="domain" options="{\'model\': \'partner\'}"/>' +
'<field name="int_field" invisible="1"/>' +
'</form>',
res_id: 1,
session: {
user_context: {uid: 14},
},
});
assert.strictEqual(form.$('.o_read_mode').text(), "This domain is not supported.",
"The widget should not crash the view, but gracefully admit its failure.");
form.destroy();
});
QUnit.test('basic domain field usage is ok', function (assert) {
assert.expect(6);