@@ -3605,6 +3605,71 @@ describe('runtime i18n', () => {
36053605 'translatedText value' ,
36063606 ) ;
36073607 } ) ;
3608+
3609+ describe ( 'attribute sanitization' , ( ) => {
3610+ @Component ( { template : '' } )
3611+ class SanitizeAppComp {
3612+ url = 'javascript:alert("oh no")' ;
3613+ count = 0 ;
3614+ }
3615+
3616+ it ( 'should sanitize translated attribute binding' , ( ) => {
3617+ const fixture = initWithTemplate ( SanitizeAppComp , '<a [attr.href]="url" i18n-href></a>' ) ;
3618+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3619+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3620+ } ) ;
3621+
3622+ it ( 'should sanitize translated property binding' , ( ) => {
3623+ const fixture = initWithTemplate ( SanitizeAppComp , '<a [href]="url" i18n-href></a>' ) ;
3624+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3625+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3626+ } ) ;
3627+
3628+ it ( 'should sanitize translated interpolation' , ( ) => {
3629+ const fixture = initWithTemplate ( SanitizeAppComp , '<a href="{{url}}" i18n-href></a>' ) ;
3630+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3631+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3632+ } ) ;
3633+
3634+ it ( 'should sanitize interpolation inside translated element' , ( ) => {
3635+ const fixture = initWithTemplate ( SanitizeAppComp , `<div i18n><a href="{{url}}"></a></div>` ) ;
3636+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3637+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3638+ } ) ;
3639+
3640+ it ( 'should sanitize attribute binding inside translated element' , ( ) => {
3641+ const fixture = initWithTemplate (
3642+ SanitizeAppComp ,
3643+ `<div i18n><a [attr.href]="url"></a></div>` ,
3644+ ) ;
3645+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3646+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3647+ } ) ;
3648+
3649+ it ( 'should sanitize property binding inside translated element' , ( ) => {
3650+ const fixture = initWithTemplate ( SanitizeAppComp , `<div i18n><a [href]="url"></a></div>` ) ;
3651+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3652+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3653+ } ) ;
3654+
3655+ it ( 'should sanitize property binding inside an ICU' , ( ) => {
3656+ const fixture = initWithTemplate (
3657+ SanitizeAppComp ,
3658+ `<div i18n>{count, plural,
3659+ =0 {no <strong>link</strong> yet}
3660+ other {{{count}} Here is the <a href="{{url}}">link</a>!}
3661+ }</div>` ,
3662+ ) ;
3663+
3664+ expect ( fixture . nativeElement . querySelector ( 'a' ) ) . toBeFalsy ( ) ;
3665+
3666+ fixture . componentInstance . count = 1 ;
3667+ fixture . detectChanges ( ) ;
3668+ const link : HTMLAnchorElement = fixture . nativeElement . querySelector ( 'a' ) ;
3669+ expect ( link ) . toBeTruthy ( ) ;
3670+ expect ( link . getAttribute ( 'href' ) ) . toMatch ( / ^ u n s a f e : / ) ;
3671+ } ) ;
3672+ } ) ;
36083673} ) ;
36093674
36103675function initWithTemplate ( compType : Type < any > , template : string ) {
0 commit comments