[FIX] qweb: protect scope in t-call writing recursively

Have something like
```xml
 <div t-name="Parent">
   <t t-call="nodeTemplate">
     <t t-set="recursive_idx" t-value="1"/>
     <t t-set="node" t-value="root"/>
   </t>
 </div>

 <div t-name="nodeTemplate">
   <t t-set="recursive_idx" t-value="recursive_idx + 1"/>
   <p><t t-esc="node.val"/> <t t-esc="recursive_idx"/></p>
   <t t-foreach="node.children or []" t-as="subtree">
     <t t-call="nodeTemplate">
       <t t-set="node" t-value="subtree"/>
     </t>
   </t>
 </div>
```

Where we want to propagate a recursion index through recursive t-calls

Before this commit, it did not work as we protected the scope in order
to not leak, in the wronf manner. Namely the protected scope only took
firt level prototype properties of the original scope.

After this commit, this case works as we mark the scope as read only

solves #672
This commit is contained in:
lucas
2020-03-11 20:18:28 +01:00
committed by Géry Debongnie
parent b4ad14edc0
commit c469cac315
5 changed files with 171 additions and 30 deletions
+4 -3
View File
@@ -196,11 +196,12 @@ export class CompilationContext {
const protectID = this.generateID();
this.rootContext.protectedScopeNumber++;
this.rootContext.shouldDefineScope = true;
const scopeExpr = codeBlock
? `Object.create(scope);`
: `Object.assign(Object.create(context), scope);`;
const scopeExpr = `Object.create(scope);`;
this.addLine(`let _origScope${protectID} = scope;`);
this.addLine(`scope = ${scopeExpr}`);
if (!codeBlock) {
this.addLine(`scope.__access_mode__ = 'ro';`);
}
return protectID;
}
stopProtectScope(protectID: number) {
+1 -1
View File
@@ -133,7 +133,7 @@ const UTILS: Utils = {
},
getScope(obj, property: string) {
const obj0 = obj;
while (obj && !obj.hasOwnProperty(property)) {
while (obj && !obj.hasOwnProperty(property) && !(obj.hasOwnProperty('__access_mode__') && obj.__access_mode__ === 'ro')) {
const newObj = obj.__proto__;
if (!newObj || isComponent(newObj)) {
return obj0;