Skip to content

Commit f95730b

Browse files
marclavalkara
authored andcommitted
fix(ivy): elements properties should not be stringified (angular#22683)
PR Close angular#22683
1 parent cd58c0a commit f95730b

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

packages/core/src/render3/instructions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,9 @@ export function elementProperty<T>(
755755
setInputsForProperty(dataValue, value);
756756
markDirtyIfOnPush(node);
757757
} else {
758-
value = (sanitizer != null ? sanitizer(value) : stringify(value)) as any;
758+
// It is assumed that the sanitizer is only added when the compiler determines that the property
759+
// is risky, so sanitization can be done without further checks.
760+
value = sanitizer != null ? (sanitizer(value) as any) : value;
759761
const native = node.native;
760762
isProceduralRenderer(renderer) ? renderer.setProperty(native, propName, value) :
761763
(native.setProperty ? native.setProperty(propName, value) :

packages/core/test/render3/compiler_canonical/sanitize_spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ describe('compiler sanitization', () => {
2525

2626
@Component({
2727
selector: 'my-component',
28-
template: `<div [innerHTML]="innerHTML"></div>` +
28+
template: `<div [innerHTML]="innerHTML" [hidden]="hidden"></div>` +
2929
`<img [style.background-image]="style" [src]="src">` +
3030
`<script [attr.src]=src></script>`
3131
})
3232
class MyComponent {
3333
innerHTML: string = '<frame></frame>';
34+
hidden: boolean = true;
3435
style: string = `url("http://evil")`;
3536
url: string = 'javascript:evil()';
3637

@@ -47,6 +48,7 @@ describe('compiler sanitization', () => {
4748
$r3$.ɵe();
4849
}
4950
$r3$.ɵp(0, 'innerHTML', $r3$.ɵb(ctx.innerHTML), $r3$.ɵsanitizeHtml);
51+
$r3$.ɵp(0, 'hidden', $r3$.ɵb(ctx.hidden));
5052
$r3$.ɵs(1, 'background-image', $r3$.ɵb(ctx.style), $r3$.ɵsanitizeStyle);
5153
$r3$.ɵp(1, 'src', $r3$.ɵb(ctx.url), $r3$.ɵsanitizeUrl);
5254
$r3$.ɵa(1, 'srcset', $r3$.ɵb(ctx.url), $r3$.ɵsanitizeUrl);
@@ -59,6 +61,7 @@ describe('compiler sanitization', () => {
5961
const div = getHostElement(myComponent).querySelector('div') !;
6062
// because sanitizer removed it is working.
6163
expect(div.innerHTML).toEqual('');
64+
expect(div.hidden).toEqual(true);
6265

6366
const img = getHostElement(myComponent).querySelector('img') !;
6467
// because sanitizer removed it is working.

packages/core/test/render3/instructions_spec.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe('instructions', () => {
3434
});
3535

3636
describe('elementProperty', () => {
37-
it('should use sanitizer function', () => {
37+
it('should use sanitizer function when available', () => {
3838
const t = new TemplateFixture(createDiv);
3939

4040
t.update(() => elementProperty(0, 'title', 'javascript:true', sanitizeUrl));
@@ -45,6 +45,14 @@ describe('instructions', () => {
4545
0, 'title', bypassSanitizationTrustUrl('javascript:false'), sanitizeUrl));
4646
expect(t.html).toEqual('<div title="javascript:false"></div>');
4747
});
48+
49+
it('should not stringify non string values', () => {
50+
const t = new TemplateFixture(createDiv);
51+
52+
t.update(() => elementProperty(0, 'hidden', false));
53+
// The hidden property would be true if `false` was stringified into `"false"`.
54+
expect((t.hostNode.native as HTMLElement).querySelector('div') !.hidden).toEqual(false);
55+
});
4856
});
4957

5058
describe('elementStyle', () => {

0 commit comments

Comments
 (0)