[IMP] components: crash when using unknown suffix/modifiers

This commit is contained in:
Géry Debongnie
2022-01-19 11:35:34 +01:00
committed by aab-odoo
parent f7843c7c00
commit b06791c950
4 changed files with 35 additions and 5 deletions
+9 -1
View File
@@ -39,6 +39,7 @@ export interface CodeGenOptions extends Config {
// of HTML (as we will parse it as xml later) // of HTML (as we will parse it as xml later)
const xmlDoc = document.implementation.createDocument(null, null, null); const xmlDoc = document.implementation.createDocument(null, null, null);
const MODS = new Set(["stop", "capture", "prevent", "self", "synthetic"]);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// BlockDescription // BlockDescription
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -504,7 +505,12 @@ export class CodeGenerator {
const modifiers = rawEvent const modifiers = rawEvent
.split(".") .split(".")
.slice(1) .slice(1)
.map((m) => `"${m}"`); .map((m) => {
if (!MODS.has(m)) {
throw new Error(`Unknown event modifier: '${m}'`);
}
return `"${m}"`;
});
let modifiersCode = ""; let modifiersCode = "";
if (modifiers.length) { if (modifiers.length) {
modifiersCode = `${modifiers.join(",")}, `; modifiersCode = `${modifiers.join(",")}, `;
@@ -1022,6 +1028,8 @@ export class CodeGenerator {
this.helpers.add("bind"); this.helpers.add("bind");
propName = name; propName = name;
propValue = `bind(ctx, ${propValue})`; propValue = `bind(ctx, ${propValue})`;
} else {
throw new Error("Invalid prop suffix");
} }
} }
propName = /^[a-z_]+$/i.test(propName) ? propName : `'${propName}'`; propName = /^[a-z_]+$/i.test(propName) ? propName : `'${propName}'`;
+8
View File
@@ -480,6 +480,14 @@ describe("t-on", () => {
button.click(); button.click();
}); });
test("t-on crashes when used with unknown modifier", async () => {
const template = `<div t-on-click.somemodifier="onClick" />`;
let owner = { onClick(e: Event) {} };
expect(() => mountToFixture(template, owner)).toThrowError("Unknown event modifier");
});
test("t-on combined with t-esc", async () => { test("t-on combined with t-esc", async () => {
expect.assertions(3); expect.assertions(3);
const template = `<div><button t-on-click="onClick" t-esc="text"/></div>`; const template = `<div><button t-on-click="onClick" t-esc="text"/></div>`;
@@ -122,7 +122,7 @@ exports[`basics support prop names that aren't valid bare object property names
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") { return function template(ctx, node, key = \\"\\") {
return component(\`Child\`, {'some-dashed-prop': 5,'a.b': 'keyword prop'}, key + \`__1\`, node, ctx); return component(\`Child\`, {'some-dashed-prop': 5}, key + \`__1\`, node, ctx);
} }
}" }"
`; `;
+17 -3
View File
@@ -142,17 +142,16 @@ describe("basics", () => {
}); });
test("support prop names that aren't valid bare object property names", async () => { test("support prop names that aren't valid bare object property names", async () => {
expect.assertions(4); expect.assertions(3);
class Child extends Component { class Child extends Component {
static template = xml`<button t-on-click="props.onClick"/>`; static template = xml`<button t-on-click="props.onClick"/>`;
setup() { setup() {
expect(this.props["some-dashed-prop"]).toBe(5); expect(this.props["some-dashed-prop"]).toBe(5);
expect(this.props["a.b"]).toBe("keyword prop");
} }
} }
class Parent extends Component { class Parent extends Component {
static template = xml`<Child some-dashed-prop="5" a.b="'keyword prop'"/>`; static template = xml`<Child some-dashed-prop="5"/>`;
static components = { Child }; static components = { Child };
} }
await mount(Parent, fixture); await mount(Parent, fixture);
@@ -225,3 +224,18 @@ test("bound functions is referentially equal after update", async () => {
expect(fixture.innerHTML).toBe("3"); expect(fixture.innerHTML).toBe("3");
expect(isEqual).toBe(true); expect(isEqual).toBe(true);
}); });
test("throw if prop uses an unknown suffix", async () => {
class Child extends Component {
static template = xml`<t t-esc="props.val"/>`;
}
class Parent extends Component {
static template = xml`<Child val.somesuffix="state.val"/>`;
static components = { Child };
}
await expect(async () => {
await mount(Parent, fixture);
}).rejects.toThrowError("Invalid prop suffix");
});