@@ -290,3 +290,135 @@ describe('NotificationConfiguration.restrictSupportedNotificationBasedOnLifecycl
290290 expect ( supportedNotificationEvents . has ( 's3:ObjectCreated:*' ) ) . toBeTruthy ( ) ;
291291 } ) ;
292292} ) ;
293+
294+ describe ( 'NotificationConfiguration.getConfigXML - XML escaping for special characters' , ( ) => {
295+ const specialCharacters = [ '&' , '<' , '>' , '"' , "'" ] ;
296+
297+ specialCharacters . forEach ( char =>
298+ it ( `should escape \`${ char } \` in notification ID and generate valid XML` , done => {
299+ const config = {
300+ queueConfig : [ {
301+ id : `test-id${ char } value` ,
302+ queueArn : 'arn:scality:bucketnotif:::target' ,
303+ events : [ 's3:ObjectCreated:*' ] ,
304+ filterRules : [ ] ,
305+ } ] ,
306+ } ;
307+
308+ const xml = NotificationConfiguration . getConfigXML ( config ) ;
309+
310+ parseString ( xml , ( err , result ) => {
311+ assert . ifError ( err ) ;
312+ const queueConfig = result . NotificationConfiguration . QueueConfiguration [ 0 ] ;
313+ assert . strictEqual ( queueConfig . Id [ 0 ] , `test-id${ char } value` ) ;
314+ done ( ) ;
315+ } ) ;
316+ } )
317+ ) ;
318+
319+ specialCharacters . forEach ( char =>
320+ it ( `should escape \`${ char } \` in queue ARN` , done => {
321+ const config = {
322+ queueConfig : [ {
323+ id : 'test-id' ,
324+ queueArn : `arn:scality:bucketnotif:::queue${ char } name` ,
325+ events : [ 's3:ObjectCreated:*' ] ,
326+ filterRules : [ ] ,
327+ } ] ,
328+ } ;
329+
330+ const xml = NotificationConfiguration . getConfigXML ( config ) ;
331+
332+ parseString ( xml , ( err , result ) => {
333+ assert . ifError ( err ) ;
334+ const queueConfig = result . NotificationConfiguration . QueueConfiguration [ 0 ] ;
335+ assert . strictEqual ( queueConfig . Queue [ 0 ] , `arn:scality:bucketnotif:::queue${ char } name` ) ;
336+ done ( ) ;
337+ } ) ;
338+ } )
339+ ) ;
340+
341+ specialCharacters . forEach ( char =>
342+ it ( `should escape \`${ char } \` in filter rule name and value` , done => {
343+ const config = {
344+ queueConfig : [ {
345+ id : 'test-id' ,
346+ queueArn : 'arn:scality:bucketnotif:::target' ,
347+ events : [ 's3:ObjectCreated:*' ] ,
348+ filterRules : [ {
349+ name : `Prefix${ char } Name` ,
350+ value : `logs/${ char } path` ,
351+ } ] ,
352+ } ] ,
353+ } ;
354+
355+ const xml = NotificationConfiguration . getConfigXML ( config ) ;
356+
357+ parseString ( xml , ( err , result ) => {
358+ assert . ifError ( err ) ;
359+ const queueConfig = result . NotificationConfiguration . QueueConfiguration [ 0 ] ;
360+ const filterRule = queueConfig . Filter [ 0 ] . S3Key [ 0 ] . FilterRule [ 0 ] ;
361+ assert . strictEqual ( filterRule . Name [ 0 ] , `Prefix${ char } Name` ) ;
362+ assert . strictEqual ( filterRule . Value [ 0 ] , `logs/${ char } path` ) ;
363+ done ( ) ;
364+ } ) ;
365+ } )
366+ ) ;
367+
368+ it ( 'should escape multiple special characters across all fields' , done => {
369+ const config = {
370+ queueConfig : [ {
371+ id : 'id<test>&\'data\'' ,
372+ queueArn : 'arn:scality:bucketnotif:::target&<queue>' ,
373+ events : [ 's3:ObjectCreated:*' ] ,
374+ filterRules : [ {
375+ name : 'Prefix' ,
376+ value : '<path>&"value"' ,
377+ } ] ,
378+ } ] ,
379+ } ;
380+
381+ const xml = NotificationConfiguration . getConfigXML ( config ) ;
382+
383+ parseString ( xml , ( err , result ) => {
384+ assert . ifError ( err ) ;
385+ const queueConfig = result . NotificationConfiguration . QueueConfiguration [ 0 ] ;
386+ assert . strictEqual ( queueConfig . Id [ 0 ] , 'id<test>&\'data\'' ) ;
387+ assert . strictEqual ( queueConfig . Queue [ 0 ] , 'arn:scality:bucketnotif:::target&<queue>' ) ;
388+ const filterRule = queueConfig . Filter [ 0 ] . S3Key [ 0 ] . FilterRule [ 0 ] ;
389+ assert . strictEqual ( filterRule . Value [ 0 ] , '<path>&"value"' ) ;
390+ done ( ) ;
391+ } ) ;
392+ } ) ;
393+
394+ it ( 'should handle multiple filter rules with special characters' , done => {
395+ const config = {
396+ queueConfig : [ {
397+ id : 'test-id' ,
398+ queueArn : 'arn:scality:bucketnotif:::target' ,
399+ events : [ 's3:ObjectCreated:*' ] ,
400+ filterRules : [
401+ {
402+ name : 'Prefix' ,
403+ value : 'logs/<app>&env' ,
404+ } ,
405+ {
406+ name : 'Suffix' ,
407+ value : '.log&.txt' ,
408+ } ,
409+ ] ,
410+ } ] ,
411+ } ;
412+
413+ const xml = NotificationConfiguration . getConfigXML ( config ) ;
414+
415+ parseString ( xml , ( err , result ) => {
416+ assert . ifError ( err ) ;
417+ const queueConfig = result . NotificationConfiguration . QueueConfiguration [ 0 ] ;
418+ const filterRules = queueConfig . Filter [ 0 ] . S3Key [ 0 ] . FilterRule ;
419+ assert . strictEqual ( filterRules [ 0 ] . Value [ 0 ] , 'logs/<app>&env' ) ;
420+ assert . strictEqual ( filterRules [ 1 ] . Value [ 0 ] , '.log&.txt' ) ;
421+ done ( ) ;
422+ } ) ;
423+ } ) ;
424+ } ) ;
0 commit comments