From 6540757d4af61c57d0ab075c00c7bb02c3fec7b4 Mon Sep 17 00:00:00 2001 From: Mathieu Duckerts-Antoine Date: Thu, 23 Mar 2023 16:48:21 +0000 Subject: [PATCH] [FIX] web: Domain: improve validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We make the class Domain detect more invalid domains. closes odoo/odoo#116471 Signed-off-by: Géry Debongnie --- addons/web/static/src/core/domain.js | 21 +++++++++++++++---- addons/web/static/tests/core/domain_tests.js | 6 ++++++ .../tests/views/fields/domain_field_tests.js | 7 +++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/addons/web/static/src/core/domain.js b/addons/web/static/src/core/domain.js index b7d2f5cf6c4..7db8352c0af 100644 --- a/addons/web/static/src/core/domain.js +++ b/addons/web/static/src/core/domain.js @@ -230,10 +230,23 @@ function normalizeDomainAST(domain, op = "&") { } let expected = 1; for (const child of domain.value) { - if (child.type === 1 /* String */ && (child.value === "&" || child.value === "|")) { - expected++; - } else if (child.type !== 1 /* String */ || child.value !== "!") { - expected--; + switch (child.type) { + case 1 /* String */: + if (child.value === "&" || child.value === "|") { + expected++; + } else if (child.value !== "!") { + throw new InvalidDomainError("Invalid domain AST"); + } + break; + case 4: /* list */ + case 10 /* tuple */: + if (child.value.length === 3) { + expected--; + break; + } + throw new InvalidDomainError("Invalid domain AST"); + default: + throw new InvalidDomainError("Invalid domain AST"); } } const values = domain.value.slice(); diff --git a/addons/web/static/tests/core/domain_tests.js b/addons/web/static/tests/core/domain_tests.js index 7e6816c6f87..a3f7fe77538 100644 --- a/addons/web/static/tests/core/domain_tests.js +++ b/addons/web/static/tests/core/domain_tests.js @@ -358,6 +358,12 @@ QUnit.module("domain", {}, () => { /invalid domain .* \(missing 1 segment/ ); assert.throws(() => new Domain(["!"]), /invalid domain .* \(missing 1 segment/); + assert.throws(() => new Domain(`[(1, 2)]`), /Invalid domain AST/); + assert.throws(() => new Domain(`[(1, 2, 3, 4)]`), /Invalid domain AST/); + assert.throws(() => new Domain(`["a"]`), /Invalid domain AST/); + assert.throws(() => new Domain(`[1]`), /Invalid domain AST/); + assert.throws(() => new Domain(`[x]`), /Invalid domain AST/); + assert.throws(() => new Domain(`[True]`), /Invalid domain AST/); // will possibly change with CHM work }); QUnit.test("follow relations", function (assert) { diff --git a/addons/web/static/tests/views/fields/domain_field_tests.js b/addons/web/static/tests/views/fields/domain_field_tests.js index f4a64d422b9..cba2ad071be 100644 --- a/addons/web/static/tests/views/fields/domain_field_tests.js +++ b/addons/web/static/tests/views/fields/domain_field_tests.js @@ -595,7 +595,7 @@ QUnit.module("Fields", (hooks) => { "2 record(s)" ); - await editInput(target, ".o_domain_debug_input", "[['abc']]"); + await editInput(target, ".o_domain_debug_input", "[['abc', '=', 1]]"); // the count should not be re-computed when editing with the textarea assert.strictEqual( target.querySelector(".o_domain_show_selection_button").textContent.trim(), @@ -603,6 +603,9 @@ QUnit.module("Fields", (hooks) => { ); assert.verifySteps([]); + await editInput(target, ".o_domain_debug_input", "[['abc']]"); + assert.verifySteps([]); + await clickSave(target); assert.hasClass( target.querySelector(".o_field_domain"), @@ -614,7 +617,7 @@ QUnit.module("Fields", (hooks) => { ".o_form_view .o_form_editable", "the view is still in edit mode" ); - assert.verifySteps(['[["abc"]]']); + assert.verifySteps([]); } );