fix(DomSchemaRegistry): detect invalid elements
This commit is contained in:
@ -27,8 +27,10 @@ export interface ModuleWithProviders {
|
||||
export interface SchemaMetadata { name: string; }
|
||||
|
||||
/**
|
||||
* Defines a schema that will allow any property on elements with a `-` in their name,
|
||||
* which is the common rule for custom elements.
|
||||
* Defines a schema that will allow:
|
||||
* - any non-angular elements with a `-` in their name,
|
||||
* - any properties on elements with a `-` in their name which is the common rule for custom
|
||||
* elements.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
@ -161,6 +163,18 @@ export class NgModuleMetadata extends InjectableMetadata implements NgModuleMeta
|
||||
*/
|
||||
bootstrap: Array<Type<any>|any[]>;
|
||||
|
||||
/**
|
||||
* Elements and properties that are not angular Components nor Directives have to be declared in
|
||||
* the schema.
|
||||
*
|
||||
* Available schemas:
|
||||
* - `NO_ERRORS_SCHEMA`: any elements and properties are allowed,
|
||||
* - `CUSTOM_ELEMENTS_SCHEMA`: any custom elements (tag name has "-") with any properties are
|
||||
* allowed.
|
||||
*
|
||||
* @security When using one of `NO_ERRORS_SCHEMA` or `CUSTOM_ELEMENTS_SCHEMA` we're trusting that
|
||||
* allowed elements (and its properties) securely escape inputs.
|
||||
*/
|
||||
schemas: Array<SchemaMetadata|any[]>;
|
||||
|
||||
constructor(options: NgModuleMetadataType = {}) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {NgFor, NgIf} from '@angular/common';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Injectable, NO_ERRORS_SCHEMA} from '@angular/core';
|
||||
import {Component, Directive, Input} from '@angular/core/src/metadata';
|
||||
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
|
||||
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||
@ -185,9 +185,8 @@ export function main() {
|
||||
TestApp,
|
||||
UsingFor,
|
||||
],
|
||||
providers: [
|
||||
Logger,
|
||||
]
|
||||
providers: [Logger],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
}));
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {Component, ContentChildren, Directive, Inject, NgModule, QueryList, asNativeElements, forwardRef} from '@angular/core';
|
||||
import {Component, ContentChildren, Directive, Inject, NO_ERRORS_SCHEMA, NgModule, QueryList, asNativeElements, forwardRef} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
||||
@ -16,7 +16,7 @@ export function main() {
|
||||
beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); });
|
||||
|
||||
it('should instantiate components which are declared using forwardRef', () => {
|
||||
const a = TestBed.createComponent(App);
|
||||
const a = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App);
|
||||
a.detectChanges();
|
||||
expect(asNativeElements(a.debugElement.children)).toHaveText('frame(lock)');
|
||||
expect(TestBed.get(ModuleFrame)).toBeDefined();
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {ComponentFactory, Host, Inject, Injectable, Injector, NgModule, OnDestroy, OpaqueToken, ReflectiveInjector, SkipSelf, SkipSelfMetadata, forwardRef} from '@angular/core';
|
||||
import {ComponentFactory, Host, Inject, Injectable, Injector, NO_ERRORS_SCHEMA, NgModule, OnDestroy, OpaqueToken, ReflectiveInjector, SkipSelf, SkipSelfMetadata} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, PipeTransform} from '@angular/core/src/change_detection/change_detection';
|
||||
import {ComponentFactoryResolver} from '@angular/core/src/linker/component_factory_resolver';
|
||||
import {ElementRef} from '@angular/core/src/linker/element_ref';
|
||||
@ -304,7 +304,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
it('should support template directives via `<template>` elements.', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]});
|
||||
const template =
|
||||
'<template some-viewport let-greeting="someTmpl"><copy-me>{{greeting}}</copy-me></template>';
|
||||
'<template some-viewport let-greeting="someTmpl"><span>{{greeting}}</span></template>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
@ -364,7 +364,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
it('should support template directives via `template` attribute.', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]});
|
||||
const template =
|
||||
'<copy-me template="some-viewport: let greeting=someTmpl">{{greeting}}</copy-me>';
|
||||
'<span template="some-viewport: let greeting=someTmpl">{{greeting}}</span>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
@ -382,7 +382,8 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
declarations: [
|
||||
MyComp, SomeDirective, CompWithHost, ToolbarComponent, ToolbarViewContainer, ToolbarPart
|
||||
],
|
||||
imports: [CommonModule]
|
||||
imports: [CommonModule],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template =
|
||||
'<some-directive><toolbar><template toolbarpart let-toolbarProp="toolbarProp">{{ctxProp}},{{toolbarProp}},<cmp-with-host></cmp-with-host></template></toolbar></some-directive>';
|
||||
@ -640,7 +641,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
});
|
||||
|
||||
it('should create a component that injects an @Host', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeDirective, CompWithHost]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, SomeDirective, CompWithHost],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `
|
||||
<some-directive>
|
||||
<p>
|
||||
@ -656,7 +660,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
});
|
||||
|
||||
it('should create a component that injects an @Host through viewcontainer directive', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeDirective, CompWithHost]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, SomeDirective, CompWithHost],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `
|
||||
<some-directive>
|
||||
<p *ngIf="true">
|
||||
@ -879,25 +886,24 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
|
||||
describe('dynamic ViewContainers', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
// we need a module to declarate ChildCompUsingService as an entryComponent otherwise the
|
||||
// factory doesn't get created
|
||||
@NgModule({
|
||||
declarations: [MyComp, DynamicViewport, ChildCompUsingService],
|
||||
entryComponents: [ChildCompUsingService]
|
||||
entryComponents: [ChildCompUsingService],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
})
|
||||
class MyModule {
|
||||
}
|
||||
|
||||
|
||||
TestBed.configureTestingModule({imports: [MyModule]});
|
||||
TestBed.overrideComponent(
|
||||
MyComp, {add: {template: '<div><dynamic-vp #dynamic></dynamic-vp></div>'}});
|
||||
});
|
||||
|
||||
|
||||
it('should allow to create a ViewContainerRef at any bound location', async(() => {
|
||||
var fixture = TestBed.createComponent(MyComp);
|
||||
var fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
|
||||
.createComponent(MyComp);
|
||||
var tc = fixture.debugElement.children[0].children[0];
|
||||
var dynamicVp: DynamicViewport = tc.injector.get(DynamicViewport);
|
||||
dynamicVp.done.then((_) => {
|
||||
@ -945,8 +951,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
|
||||
describe('dependency injection', () => {
|
||||
it('should support bindings', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, DirectiveProvidingInjectable, DirectiveConsumingInjectable]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, DirectiveProvidingInjectable, DirectiveConsumingInjectable],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `
|
||||
<directive-providing-injectable >
|
||||
<directive-consuming-injectable #consuming>
|
||||
@ -962,8 +970,8 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
|
||||
it('should support viewProviders', () => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations:
|
||||
[MyComp, DirectiveProvidingInjectableInView, DirectiveConsumingInjectable]
|
||||
declarations: [MyComp, DirectiveProvidingInjectableInView, DirectiveConsumingInjectable],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `
|
||||
<directive-consuming-injectable #consuming>
|
||||
@ -981,7 +989,8 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
declarations: [
|
||||
MyComp, DirectiveProvidingInjectable, DirectiveContainingDirectiveConsumingAnInjectable,
|
||||
DirectiveConsumingInjectableUnbounded
|
||||
]
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `
|
||||
<directive-providing-injectable>
|
||||
@ -1007,7 +1016,8 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
MyComp, GrandParentProvidingEventBus, ParentProvidingEventBus, ChildConsumingEventBus
|
||||
]
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `
|
||||
<grand-parent-providing-event-bus>
|
||||
@ -1036,8 +1046,8 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
|
||||
it('should instantiate bindings lazily', () => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations:
|
||||
[MyComp, DirectiveConsumingInjectable, ComponentProvidingLoggingInjectable]
|
||||
declarations: [MyComp, DirectiveConsumingInjectable, ComponentProvidingLoggingInjectable],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `
|
||||
<component-providing-logging-injectable #providing>
|
||||
@ -1138,7 +1148,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
});
|
||||
|
||||
it('should provide an error context when an error happens in DI', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, DirectiveThrowingAnError]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, DirectiveThrowingAnError],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `<directive-throwing-error></directive-throwing-error>`;
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
|
||||
@ -1190,8 +1203,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
if (getDOM().supportsDOMEvents()) { // this is required to use fakeAsync
|
||||
it('should provide an error context when an error happens in an event handler',
|
||||
fakeAsync(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `<span emitter listener (event)="throwError()" #local></span>`;
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
@ -1366,7 +1381,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
|
||||
describe('property decorators', () => {
|
||||
it('should support property decorators', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithPropDecorators]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, DirectiveWithPropDecorators],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = '<with-prop-decorators elProp="aaa"></with-prop-decorators>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
@ -1377,7 +1395,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
});
|
||||
|
||||
it('should support host binding decorators', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithPropDecorators]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, DirectiveWithPropDecorators],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = '<with-prop-decorators></with-prop-decorators>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
@ -1393,7 +1414,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
|
||||
if (getDOM().supportsDOMEvents()) {
|
||||
it('should support event decorators', fakeAsync(() => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithPropDecorators]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, DirectiveWithPropDecorators],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = `<with-prop-decorators (elEvent)="ctxProp='called'">`;
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
@ -1411,7 +1435,10 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
|
||||
|
||||
it('should support host listener decorators', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithPropDecorators]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, DirectiveWithPropDecorators],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = '<with-prop-decorators></with-prop-decorators>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
@ -1426,8 +1453,11 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
}
|
||||
|
||||
it('should support defining views in the component decorator', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, ComponentWithTemplate], imports: [CommonModule]});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MyComp, ComponentWithTemplate],
|
||||
imports: [CommonModule],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
const template = '<component-with-template></component-with-template>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
@ -6,10 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Component, Directive, ElementRef, TemplateRef, ViewContainerRef, ViewEncapsulation, forwardRef} from '@angular/core';
|
||||
import {Component, Directive, ElementRef, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
||||
import {getAllDebugNodes} from '@angular/core/src/debug/debug_node';
|
||||
import {ViewMetadata} from '@angular/core/src/metadata/view';
|
||||
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
||||
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
@ -457,8 +456,8 @@ export function main() {
|
||||
main.detectChanges();
|
||||
expect(getDOM().getInnerHTML(main.debugElement.nativeElement))
|
||||
.toEqual(
|
||||
'<cmp-a><cmp-b><cmp-d><d>cmp-d</d></cmp-d></cmp-b>' +
|
||||
'<cmp-c><c>cmp-c</c></cmp-c></cmp-a>');
|
||||
'<cmp-a><cmp-b><cmp-d><i>cmp-d</i></cmp-d></cmp-b>' +
|
||||
'<cmp-c><b>cmp-c</b></cmp-c></cmp-a>');
|
||||
});
|
||||
|
||||
it('should create nested components in the right order', () => {
|
||||
@ -652,7 +651,7 @@ class Tree {
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'cmp-d', template: `<d>{{tagName}}</d>`})
|
||||
@Component({selector: 'cmp-d', template: `<i>{{tagName}}</i>`})
|
||||
class CmpD {
|
||||
tagName: string;
|
||||
constructor(elementRef: ElementRef) {
|
||||
@ -661,7 +660,7 @@ class CmpD {
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'cmp-c', template: `<c>{{tagName}}</c>`})
|
||||
@Component({selector: 'cmp-c', template: `<b>{{tagName}}</b>`})
|
||||
class CmpC {
|
||||
tagName: string;
|
||||
constructor(elementRef: ElementRef) {
|
||||
|
@ -6,14 +6,15 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Component, Directive, ElementRef, Input, QueryList, ViewChild, ViewChildren} from '@angular/core';
|
||||
import {Component, Directive, ElementRef, Input, NO_ERRORS_SCHEMA, QueryList, ViewChild, ViewChildren} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
export function main() {
|
||||
describe('ViewChild', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ViewChildTypeSelectorComponent, ViewChildStringSelectorComponent, Simple]
|
||||
declarations: [ViewChildTypeSelectorComponent, ViewChildStringSelectorComponent, Simple],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
});
|
||||
|
||||
@ -42,7 +43,8 @@ export function main() {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations:
|
||||
[ViewChildrenTypeSelectorComponent, ViewChildrenStringSelectorComponent, Simple]
|
||||
[ViewChildrenTypeSelectorComponent, ViewChildrenStringSelectorComponent, Simple],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
});
|
||||
});
|
||||
|
||||
@ -61,7 +63,8 @@ export function main() {
|
||||
TestBed.overrideComponent(
|
||||
ViewChildrenStringSelectorComponent,
|
||||
{set: {template: `<simple #child1></simple><simple #child2></simple>`}});
|
||||
const view = TestBed.createComponent(ViewChildrenStringSelectorComponent);
|
||||
const view = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
|
||||
.createComponent(ViewChildrenStringSelectorComponent);
|
||||
view.detectChanges();
|
||||
expect(view.componentInstance.children).toBeDefined();
|
||||
expect(view.componentInstance.children.length).toBe(2);
|
||||
|
Reference in New Issue
Block a user