From aa57bdbf90f2ceae4e0acf842611e2a0873cb9d2 Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Thu, 21 Feb 2019 21:33:05 -0800 Subject: [PATCH] fix(ivy): wrap "inputs" and "outputs" keys if they contain unsafe characters (#28919) Prior to this change, keys in "inputs" and "outputs" objects generated by compiler were not checked against unsafe characters. As a result, in some cases the generated code was throwing JS error. Now we check whether a given key contains any unsafe chars and wrap it in quotes if needed. PR Close #28919 --- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 22 +++++++++++++++++++ packages/compiler/src/render3/view/util.ts | 13 ++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 1e50aab87d..a54f684084 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -2148,6 +2148,28 @@ describe('ngtsc behavioral tests', () => { }); }); + it('should wrap "inputs" and "outputs" keys if they contain unsafe characters', () => { + env.tsconfig({}); + env.write(`test.ts`, ` + import {Directive} from '@angular/core'; + + @Directive({ + selector: '[somedir]', + inputs: ['input-track-type', 'inputTrackName'], + outputs: ['output-track-type', 'outputTrackName'] + }) + export class SomeDir {} + `); + + env.driveMain(); + const jsContents = env.getContents('test.js'); + const inputsAndOutputs = ` + inputs: { "input-track-type": "input-track-type", inputTrackName: "inputTrackName" }, + outputs: { "output-track-type": "output-track-type", outputTrackName: "outputTrackName" } + `; + expect(trim(jsContents)).toContain(trim(inputsAndOutputs)); + }); + it('should compile programs with typeRoots', () => { // Write out a custom tsconfig.json that includes 'typeRoots' and 'files'. 'files' is necessary // because otherwise TS picks up the testTypeRoot/test/index.d.ts file into the program diff --git a/packages/compiler/src/render3/view/util.ts b/packages/compiler/src/render3/view/util.ts index 8b3f375d16..1e533b204e 100644 --- a/packages/compiler/src/render3/view/util.ts +++ b/packages/compiler/src/render3/view/util.ts @@ -13,6 +13,16 @@ import * as t from '../r3_ast'; import {R3QueryMetadata} from './api'; import {isI18nAttribute} from './i18n/util'; +/** + * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in + * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may + * bot work in some cases when object keys are mangled by minifier. + * + * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with + * inputs that contain potentially unsafe chars. + */ +const UNSAFE_OBJECT_KEY_NAME_REGEXP = /-/g; + /** Name of the temporary to use during data binding */ export const TEMPORARY_NAME = '_t'; @@ -92,7 +102,8 @@ function mapToExpression( minifiedName = declaredName; return { key: minifiedName, - quoted: false, + // put quotes around keys that contain potentially unsafe characters + quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName), value: (keepDeclared && publicName !== declaredName) ? o.literalArr([asLiteral(publicName), asLiteral(declaredName)]) : asLiteral(publicName)