|
| 1 | +/** |
| 2 | + * @license |
| 3 | + * Copyright Google LLC All Rights Reserved. |
| 4 | + * |
| 5 | + * Use of this source code is governed by an MIT-style license that can be |
| 6 | + * found in the LICENSE file at https://angular.dev/license |
| 7 | + */ |
| 8 | + |
| 9 | +import {SecurityContext} from '../../../../core'; |
| 10 | +import * as o from '../../../../output/output_ast'; |
| 11 | +import {Identifiers} from '../../../../render3/r3_identifiers'; |
| 12 | +import * as ir from '../../ir'; |
| 13 | +import {CompilationJob} from '../compilation'; |
| 14 | +import {MATH_ML_NAMESPACE, SVG_NAMESPACE} from '../namespaces'; |
| 15 | + |
| 16 | +/** |
| 17 | + * Wraps static i18n extracted attributes in their corresponding sanitizers/validators. |
| 18 | + */ |
| 19 | +export function resolveI18nAttrSanitizers(job: CompilationJob): void { |
| 20 | + const tagNamesByElement = new Map<ir.XrefId, string>(); |
| 21 | + |
| 22 | + for (const unit of job.units) { |
| 23 | + for (const op of unit.ops()) { |
| 24 | + if (op.kind === ir.OpKind.ElementStart || op.kind === ir.OpKind.Template) { |
| 25 | + let tag = op.tag ?? ''; |
| 26 | + switch (op.namespace) { |
| 27 | + case ir.Namespace.SVG: |
| 28 | + tag = `:${SVG_NAMESPACE}:${tag}`; |
| 29 | + break; |
| 30 | + case ir.Namespace.Math: |
| 31 | + tag = `:${MATH_ML_NAMESPACE}:${tag}`; |
| 32 | + break; |
| 33 | + } |
| 34 | + |
| 35 | + tagNamesByElement.set(op.xref, tag); |
| 36 | + } |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + for (const unit of job.units) { |
| 41 | + for (const op of unit.create) { |
| 42 | + if ( |
| 43 | + op.kind === ir.OpKind.ExtractedAttribute && |
| 44 | + op.i18nContext !== null && |
| 45 | + op.expression !== null |
| 46 | + ) { |
| 47 | + const tagName = tagNamesByElement.get(op.target) ?? ''; |
| 48 | + let expr = op.expression; |
| 49 | + switch (op.securityContext) { |
| 50 | + case SecurityContext.HTML: |
| 51 | + expr = o.importExpr(Identifiers.sanitizeHtml).callFn([expr]); |
| 52 | + break; |
| 53 | + case SecurityContext.STYLE: |
| 54 | + expr = o.importExpr(Identifiers.sanitizeStyle).callFn([expr]); |
| 55 | + break; |
| 56 | + case SecurityContext.SCRIPT: |
| 57 | + expr = o.importExpr(Identifiers.sanitizeScript).callFn([expr]); |
| 58 | + break; |
| 59 | + case SecurityContext.URL: |
| 60 | + expr = o.importExpr(Identifiers.sanitizeUrl).callFn([expr]); |
| 61 | + break; |
| 62 | + case SecurityContext.RESOURCE_URL: |
| 63 | + expr = o.importExpr(Identifiers.sanitizeResourceUrl).callFn([expr]); |
| 64 | + break; |
| 65 | + case SecurityContext.ATTRIBUTE_NO_BINDING: |
| 66 | + expr = o |
| 67 | + .importExpr(Identifiers.validateAttribute) |
| 68 | + .callFn([expr, o.literal(tagName), o.literal(op.name)]); |
| 69 | + break; |
| 70 | + } |
| 71 | + op.expression = expr; |
| 72 | + } |
| 73 | + } |
| 74 | + } |
| 75 | +} |
0 commit comments