[FIX] web: domain: (=)(i)like operators

Before this commit, evaluating a domain containing a like/ilike
operator with an evaluation context in which the value was false
crashed.

Moreover, those operators were wrong w.r.t. the case sensitivity:
like was case insensitive, whereas ilike was case sensitive, and
both =like and =ilike were case insensitive.

This commit fixes thoses issues.

The first issue was spotted on our prod, as we tried to add an
invisible attrs in a form view, using the ilike operator (it thus
crashed in create mode).

The second issue was spotted while writting the test cases.

To the best of our knowledge, those operators aren't used in attrs
(for now), explaining why those issues haven't been found before.

closes odoo/odoo#70951

X-original-commit: 44e185dbd6ddeda7cdcd76882fa0bd231e9d3f37
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Aaron Bohy
2021-05-18 10:02:14 +00:00
parent 65fd6a5ef6
commit 2e030a37aa
2 changed files with 41 additions and 6 deletions
+17 -6
View File
@@ -106,20 +106,31 @@ var Domain = collections.Tree.extend({
return _.intersection(
_.isArray(this._data[2]) ? this._data[2] : [this._data[2]],
_.isArray(fieldValue) ? fieldValue : [fieldValue],
).length !== 0;;
).length !== 0;
case "not in":
return _.intersection(
_.isArray(this._data[2]) ? this._data[2] : [this._data[2]],
_.isArray(fieldValue) ? fieldValue : [fieldValue],
).length === 0;
case "like":
return (fieldValue.toLowerCase().indexOf(this._data[2].toLowerCase()) >= 0);
case "=like":
var regExp = new RegExp(this._data[2].toLowerCase().replace(/([.\[\]\{\}\+\*])/g, '\\\$1').replace(/%/g, '.*'));
return regExp.test(fieldValue.toLowerCase());
case "ilike":
if (fieldValue === false) {
return false;
}
return (fieldValue.indexOf(this._data[2]) >= 0);
case "=like":
if (fieldValue === false) {
return false;
}
return new RegExp(this._data[2].replace(/%/g, '.*')).test(fieldValue);
case "ilike":
if (fieldValue === false) {
return false;
}
return (fieldValue.toLowerCase().indexOf(this._data[2].toLowerCase()) >= 0);
case "=ilike":
if (fieldValue === false) {
return false;
}
return new RegExp(this._data[2].replace(/%/g, '.*'), 'i').test(fieldValue);
default:
throw new Error(_.str.sprintf(
@@ -158,5 +158,29 @@ QUnit.module('core', {}, function () {
assert.strictEqual(arrayToString(), '[]');
});
QUnit.test("like, =like, ilike and =ilike", function (assert) {
assert.expect(16);
assert.ok(new Domain([['a', 'like', 'value']]).compute({ a: 'value' }));
assert.ok(new Domain([['a', 'like', 'value']]).compute({ a: 'some value' }));
assert.notOk(new Domain([['a', 'like', 'value']]).compute({ a: 'Some Value' }));
assert.notOk(new Domain([['a', 'like', 'value']]).compute({ a: false }));
assert.ok(new Domain([['a', '=like', '%value']]).compute({ a: 'value' }));
assert.ok(new Domain([['a', '=like', '%value']]).compute({ a: 'some value' }));
assert.notOk(new Domain([['a', '=like', '%value']]).compute({ a: 'Some Value' }));
assert.notOk(new Domain([['a', '=like', '%value']]).compute({ a: false }));
assert.ok(new Domain([['a', 'ilike', 'value']]).compute({ a: 'value' }));
assert.ok(new Domain([['a', 'ilike', 'value']]).compute({ a: 'some value' }));
assert.ok(new Domain([['a', 'ilike', 'value']]).compute({ a: 'Some Value' }));
assert.notOk(new Domain([['a', 'ilike', 'value']]).compute({ a: false }));
assert.ok(new Domain([['a', '=ilike', '%value']]).compute({ a: 'value' }));
assert.ok(new Domain([['a', '=ilike', '%value']]).compute({ a: 'some value' }));
assert.ok(new Domain([['a', '=ilike', '%value']]).compute({ a: 'Some Value' }));
assert.notOk(new Domain([['a', '=ilike', '%value']]).compute({ a: false }));
});
});
});