[FIX] web: tolerate empty string as action context

Before this commit, calling "makeContext" with an empty string as
context description crashed. For instance, this happened with at least two
actions in Odoo:

Elearning > Courses > Contents
Fleet > Vehicules > Odometers

In both cases, the context in the action is the empty string.
Issue spotted thanks to the clickEverywhere test.

The crash was caused by the pyjs parser. This is correct (even though
the error was not clear), since an empty list of token do not represent
a valid python AST.  So, the fix is to make the makeContext function
more tolerant.

closes odoo/odoo#72490

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Géry Debongnie
2021-06-21 20:44:11 +00:00
parent 109745eac8
commit 30fce04357
5 changed files with 19 additions and 4 deletions
+4 -2
View File
@@ -16,8 +16,10 @@ import { evaluateExpr } from "./py_js/py";
export function makeContext(...contexts) {
let context = {};
for (let ctx of contexts) {
const subCtx = typeof ctx === "string" ? evaluateExpr(ctx, context) : ctx;
Object.assign(context, subCtx);
if (ctx !== "") {
const subCtx = typeof ctx === "string" ? evaluateExpr(ctx, context) : ctx;
Object.assign(context, subCtx);
}
}
return context;
}
@@ -364,5 +364,8 @@ function _parse(tokens, bp = 0) {
* @returns {AST}
*/
export function parse(tokens) {
return _parse(tokens, 0);
if (tokens.length) {
return _parse(tokens, 0);
}
throw new ParserError("Missing token");
}
@@ -16,9 +16,11 @@ QUnit.module("utils", {}, () => {
assert.deepEqual(ctx1, ctx2);
});
QUnit.test("can accept undefined", (assert) => {
QUnit.test("can accept undefined or empty string", (assert) => {
assert.deepEqual(makeContext(undefined), {});
assert.deepEqual(makeContext({ a: 1 }, undefined, { b: 2 }), { a: 1, b: 2 });
assert.deepEqual(makeContext(""), {});
assert.deepEqual(makeContext({ a: 1 }, "", { b: 2 }), { a: 1, b: 2 });
});
QUnit.test("evaluate strings", (assert) => {
@@ -12,6 +12,10 @@ QUnit.module("py", {}, () => {
assert.strictEqual(evaluateExpr('"foo"'), "foo");
});
QUnit.test("empty expression", (assert) => {
assert.throws(() => evaluateExpr(""), /Error: Missing token/);
});
QUnit.test("numbers", (assert) => {
assert.strictEqual(evaluateExpr("1.2"), 1.2);
assert.strictEqual(evaluateExpr(".12"), 0.12);
@@ -14,6 +14,10 @@ QUnit.module("py", {}, () => {
assert.deepEqual(parseExpr("None"), { type: 3 /* None */ });
});
QUnit.test("cannot parse empty string", (assert) => {
assert.throws(() => parseExpr(""), /Error: Missing token/);
});
QUnit.test("can parse unary operator -", (assert) => {
assert.deepEqual(parseExpr("-1"), {
type: 6 /* UnaryOperator */,