Skip to content

Commit 3719752

Browse files
crisbetopkozlowski-opensource
authored andcommitted
refactor(compiler): validate references in selectorless (angular#60952)
Adds the follow validations to the selectorless template parsing: * Local references with values are not allowed (e.g. `#foo="bar"`). * Multiple local references with the same on a component or directive are not allowed. PR Close angular#60952
1 parent 08512ee commit 3719752

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

packages/compiler/src/render3/r3_template_transform.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ class HtmlAstToIvyAst implements html.Visitor {
378378
i18nAttrsMeta,
379379
} = this.prepareAttributes(component.attrs, false);
380380

381+
this.validateSelectorlessReferences(references);
382+
381383
const directives = this.extractDirectives(component);
382384
let children: t.Node[];
383385

@@ -914,6 +916,8 @@ class HtmlAstToIvyAst implements html.Visitor {
914916

915917
const {attributes, parsedProperties, boundEvents, references, i18nAttrsMeta} =
916918
this.prepareAttributes(directive.attrs, false);
919+
this.validateSelectorlessReferences(references);
920+
917921
const {bound: inputs} = this.categorizePropertyAttributes(
918922
elementName,
919923
parsedProperties,
@@ -1085,6 +1089,27 @@ class HtmlAstToIvyAst implements html.Visitor {
10851089
addEvents(events, boundEvents);
10861090
}
10871091

1092+
private validateSelectorlessReferences(references: t.Reference[]): void {
1093+
if (references.length === 0) {
1094+
return;
1095+
}
1096+
1097+
const seenNames = new Set<string>();
1098+
1099+
for (const ref of references) {
1100+
if (ref.value.length > 0) {
1101+
this.reportError(
1102+
'Cannot specify a value for a local reference in this context',
1103+
ref.valueSpan || ref.sourceSpan,
1104+
);
1105+
} else if (seenNames.has(ref.name)) {
1106+
this.reportError('Duplicate reference names are not allowed', ref.sourceSpan);
1107+
} else {
1108+
seenNames.add(ref.name);
1109+
}
1110+
}
1111+
}
1112+
10881113
private reportError(
10891114
message: string,
10901115
sourceSpan: ParseSourceSpan,

packages/compiler/test/render3/r3_template_transform_spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,6 +2646,18 @@ describe('R3 template transform', () => {
26462646
/Binding is not supported in a directive context/,
26472647
);
26482648
});
2649+
2650+
it('should not allow named references', () => {
2651+
const pattern = /Cannot specify a value for a local reference in this context/;
2652+
expect(() => parseSelectorless('<MyComp #foo="bar"/>')).toThrowError(pattern);
2653+
expect(() => parseSelectorless('<div @Dir(#foo="bar")></div>')).toThrowError(pattern);
2654+
});
2655+
2656+
it('should not allow duplicate references', () => {
2657+
const pattern = /Duplicate reference names are not allowed/;
2658+
expect(() => parseSelectorless('<MyComp #foo #foo/>')).toThrowError(pattern);
2659+
expect(() => parseSelectorless('<div @Dir(#foo #foo)></div>')).toThrowError(pattern);
2660+
});
26492661
});
26502662
});
26512663
});

0 commit comments

Comments
 (0)