FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix(core): normalize tag names in runtime i18n attribute security con… · angular/angular@ff12fe5 · GitHub

Commit ff12fe5

Browse files
authored andcommitted
fix(core): normalize tag names in runtime i18n attribute security context lookup (#68925)
Normalize namespaced tag names (e.g., :xhtml:a to a) inside i18nResolveSanitizer before looking up their security context. This ensures custom namespaced tag attributes undergo correct translation sanitization at runtime. PR Close #68925
1 parent 0b07f47 commit ff12fe5

3 files changed

Lines changed: 30 additions & 21 deletions

File tree

‎packages/compiler/src/schema/dom_element_schema_registry.ts‎

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,10 @@ const STRING = 'string';
1919
const OBJECT = 'object';
2020

2121
function normalizeTagName(tagName: string): string {
22-
tagName = tagName.toLowerCase();
23-
if (tagName[0] === ':') {
24-
const [ns, name] = splitNsName(tagName, false);
22+
const tagNameLower = tagName.toLowerCase();
23+
const [ns, name] = splitNsName(tagNameLower, false);
2524

26-
return ns === SVG_NAMESPACE || ns === MATH_ML_NAMESPACE ? `:${ns}:${name}` : name;
27-
}
28-
29-
const colonIdx = tagName.indexOf(':');
30-
if (colonIdx > 0) {
31-
const ns = tagName.substring(0, colonIdx);
32-
const name = tagName.substring(colonIdx + 1);
33-
34-
return ns === SVG_NAMESPACE || ns === MATH_ML_NAMESPACE ? `:${ns}:${name}` : name;
35-
}
36-
return tagName;
25+
return ns === SVG_NAMESPACE || ns === MATH_ML_NAMESPACE ? `:${ns}:${name}` : name;
3726
}
3827

3928
/**

‎packages/compiler/test/schema/dom_element_schema_registry_spec.ts‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,17 @@ If 'onAnything' is a directive input, make sure the directive is imported by the
207207
describe('Custom XML / XHTML namespaces', () => {
208208
it('should support elements with custom namespaces', () => {
209209
expect(registry.hasElement(':xhtml:a', [])).toBeTruthy();
210-
expect(registry.hasElement('xhtml:a', [])).toBeTruthy();
211210
expect(registry.hasElement(':foo:div', [])).toBeTruthy();
212-
expect(registry.hasElement('foo:div', [])).toBeTruthy();
213211
});
214212

215213
it('should support properties on custom namespaced elements', () => {
216214
expect(registry.hasProperty(':xhtml:a', 'href', [])).toBeTruthy();
217-
expect(registry.hasProperty('xhtml:a', 'href', [])).toBeTruthy();
218215
expect(registry.hasProperty(':foo:div', 'id', [])).toBeTruthy();
219-
expect(registry.hasProperty('foo:div', 'id', [])).toBeTruthy();
220216
});
221217

222218
it('should return correct security contexts for custom namespaced elements', () => {
223219
expect(registry.securityContext(':xhtml:a', 'href', false)).toBe(SecurityContext.URL);
224-
expect(registry.securityContext('xhtml:a', 'href', false)).toBe(SecurityContext.URL);
225220
expect(registry.securityContext(':foo:div', 'innerHTML', false)).toBe(SecurityContext.HTML);
226-
expect(registry.securityContext('foo:div', 'innerHTML', false)).toBe(SecurityContext.HTML);
227221
});
228222
});
229223

‎packages/core/src/render3/i18n/i18n_parse.ts‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import {
7373
} from './i18n_util';
7474
import {createTNodeAtIndex} from '../tnode_manipulation';
7575
import {allocExpando} from '../view/construction';
76+
import {MATH_ML_NAMESPACE, SVG_NAMESPACE} from '../namespaces';
7677

7778
const BINDING_REGEXP = /(\d+):?\d*/gi;
7879
const ICU_REGEXP = /({\s*\d+:?\d*\s*,\s*\S{6}\s*,[\s\S]*})/gi;
@@ -984,9 +985,34 @@ function addCreateAttribute(
984985
create.push((newIndex << IcuCreateOpCode.SHIFT_REF) | IcuCreateOpCode.Attr, attrName, attrValue);
985986
}
986987

988+
function splitNsName(elementName: string, fatal: boolean = true): [string | null, string] {
989+
if (elementName[0] != ':') {
990+
return [null, elementName];
991+
}
992+
993+
const colonIndex = elementName.indexOf(':', 1);
994+
995+
if (colonIndex === -1) {
996+
if (fatal) {
997+
throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
998+
} else {
999+
return [null, elementName];
1000+
}
1001+
}
1002+
1003+
return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
1004+
}
1005+
1006+
function normalizeTagName(tagName: string): string {
1007+
const tagNameLower = tagName.toLowerCase();
1008+
const [ns, name] = splitNsName(tagNameLower, false);
1009+
1010+
return ns === SVG_NAMESPACE || ns === MATH_ML_NAMESPACE ? `:${ns}:${name}` : name;
1011+
}
1012+
9871013
function i18nResolveSanitizer(attrName: string, tagName?: string): SanitizerFn | null {
9881014
const lowerAttrName = attrName.toLowerCase();
989-
const lowerTagName = tagName ? tagName.toLowerCase() : '*';
1015+
const lowerTagName = tagName ? normalizeTagName(tagName) : '*';
9901016
const schema = SECURITY_SCHEMA();
9911017
const schemaContext =
9921018
schema[`${lowerTagName}|${lowerAttrName}`] ||

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL