From d061adc02db9057d67de2f74b6e880005582e674 Mon Sep 17 00:00:00 2001 From: Chuck Jazdzewski Date: Thu, 5 Jan 2017 15:22:38 -0800 Subject: [PATCH] fix(compiler): avoid evaluating arguments to unknown decorators Fixes #13605 --- .../compiler/src/aot/static_reflector.ts | 7 ++-- .../test/aot/static_reflector_spec.ts | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/modules/@angular/compiler/src/aot/static_reflector.ts b/modules/@angular/compiler/src/aot/static_reflector.ts index 03f6fc36dc..4c073d4d1b 100644 --- a/modules/@angular/compiler/src/aot/static_reflector.ts +++ b/modules/@angular/compiler/src/aot/static_reflector.ts @@ -322,6 +322,7 @@ export class StaticReflector implements ReflectorReader { if (value && (depth != 0 || value.__symbolic != 'error')) { const parameters: string[] = targetFunction['parameters']; const defaults: any[] = targetFunction.defaults; + args = args.map(arg => simplifyInContext(context, arg, depth + 1)); if (defaults && defaults.length > args.length) { args.push(...defaults.slice(args.length).map((value: any) => simplify(value))); } @@ -511,15 +512,15 @@ export class StaticReflector implements ReflectorReader { return context; } const argExpressions: any[] = expression['arguments'] || []; - const args = - argExpressions.map(arg => simplifyInContext(context, arg, depth + 1)); let converter = self.conversionMap.get(staticSymbol); if (converter) { + const args = + argExpressions.map(arg => simplifyInContext(context, arg, depth + 1)); return converter(context, args); } else { // Determine if the function is one we can simplify. const targetFunction = resolveReferenceValue(staticSymbol); - return simplifyCall(staticSymbol, targetFunction, args); + return simplifyCall(staticSymbol, targetFunction, argExpressions); } } break; diff --git a/modules/@angular/compiler/test/aot/static_reflector_spec.ts b/modules/@angular/compiler/test/aot/static_reflector_spec.ts index 515b924564..3e02898cb4 100644 --- a/modules/@angular/compiler/test/aot/static_reflector_spec.ts +++ b/modules/@angular/compiler/test/aot/static_reflector_spec.ts @@ -449,6 +449,40 @@ describe('StaticReflector', () => { expect(annotations[0].providers[0].useValue.members[0]).toEqual('staticMethod'); }); + // #13605 + it('should not throw on unknown decorators', () => { + const data = Object.create(DEFAULT_TEST_DATA); + const file = '/tmp/src/app.component.ts'; + data[file] = ` + import { Component } from '@angular/core'; + + export const enum TypeEnum { + type + } + + export function MyValidationDecorator(p1: any, p2: any): any { + return null; + } + + export function ValidationFunction(a1: any): any { + return null; + } + + @Component({ + selector: 'my-app', + template: "

Hello {{name}}

", + }) + export class AppComponent { + name = 'Angular'; + + @MyValidationDecorator( TypeEnum.type, ValidationFunction({option: 'value'})) + myClassProp: number; + }`; + init(data); + const appComponent = reflector.getStaticSymbol(file, 'AppComponent'); + expect(() => reflector.propMetadata(appComponent)).not.toThrow(); + }); + describe('inheritance', () => { class ClassDecorator { constructor(public value: any) {}