@@ -3534,6 +3534,71 @@ describe('runtime i18n', () => {
35343534 'translatedText value' ,
35353535 ) ;
35363536 } ) ;
3537+
3538+ describe ( 'attribute sanitization' , ( ) => {
3539+ @Component ( { template : '' } )
3540+ class SanitizeAppComp {
3541+ url = 'javascript:alert("oh no")' ;
3542+ count = 0 ;
3543+ }
3544+
3545+ it ( 'should sanitize translated attribute binding' , ( ) => {
3546+ const fixture = initWithTemplate ( SanitizeAppComp , '<a [attr.href]="url" i18n-href></a>' ) ;
3547+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3548+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3549+ } ) ;
3550+
3551+ it ( 'should sanitize translated property binding' , ( ) => {
3552+ const fixture = initWithTemplate ( SanitizeAppComp , '<a [href]="url" i18n-href></a>' ) ;
3553+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3554+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3555+ } ) ;
3556+
3557+ it ( 'should sanitize translated interpolation' , ( ) => {
3558+ const fixture = initWithTemplate ( SanitizeAppComp , '<a href="{{url}}" i18n-href></a>' ) ;
3559+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3560+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3561+ } ) ;
3562+
3563+ it ( 'should sanitize interpolation inside translated element' , ( ) => {
3564+ const fixture = initWithTemplate ( SanitizeAppComp , `<div i18n><a href="{{url}}"></a></div>` ) ;
3565+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3566+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3567+ } ) ;
3568+
3569+ it ( 'should sanitize attribute binding inside translated element' , ( ) => {
3570+ const fixture = initWithTemplate (
3571+ SanitizeAppComp ,
3572+ `<div i18n><a [attr.href]="url"></a></div>` ,
3573+ ) ;
3574+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3575+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3576+ } ) ;
3577+
3578+ it ( 'should sanitize property binding inside translated element' , ( ) => {
3579+ const fixture = initWithTemplate ( SanitizeAppComp , `<div i18n><a [href]="url"></a></div>` ) ;
3580+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3581+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3582+ } ) ;
3583+
3584+ it ( 'should sanitize property binding inside an ICU' , ( ) => {
3585+ const fixture = initWithTemplate (
3586+ SanitizeAppComp ,
3587+ `<div i18n>{count, plural,
3588+ =0 {no <strong>link</strong> yet}
3589+ other {{{count}} Here is the <a href="{{url}}">link</a>!}
3590+ }</div>` ,
3591+ ) ;
3592+
3593+ expect ( fixture . nativeElement . querySelector ( 'a' ) ) . toBeFalsy ( ) ;
3594+
3595+ fixture . componentInstance . count = 1 ;
3596+ fixture . detectChanges ( ) ;
3597+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3598+ expect ( link ) . toBeTruthy ( ) ;
3599+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3600+ } ) ;
3601+ } ) ;
35373602} ) ;
35383603
35393604function initWithTemplate ( compType : Type < any > , template : string ) {
0 commit comments