NDEFMessage_recursion-limit.https.window.js (6178B)
1 'use strict'; 2 3 test(() => { 4 let recordInit = {recordType: 'w3.org:ExternalRecord'}; 5 const messageInit = {records: [recordInit]}; 6 recordInit.data = messageInit; 7 8 assert_throws_js(TypeError, () => { 9 new NDEFMessage(messageInit); 10 }, 'Creating a recursive NDEFMessage throws a TypeError'); 11 assert_throws_js(TypeError, () => { 12 new NDEFRecord(recordInit); 13 }, 'Creating a recursive NDEFRecord throws a TypeError'); 14 assert_throws_js(TypeError, () => { 15 new NDEFReadingEvent('message', {message: messageInit}); 16 }, 'Creating a recursive NDEFReadingEvent throws a TypeError'); 17 }, 'NDEFRecord and NDEFMessage cycle in external records'); 18 19 test(() => { 20 let recordInit = {recordType: ':local'}; 21 const messageInit = {records: [recordInit]}; 22 recordInit.data = messageInit; 23 24 const externalRecordMessageInit = { 25 records: [{recordType: 'w3.org:ExternalRecord', data: messageInit}] 26 }; 27 28 assert_throws_js(TypeError, () => { 29 new NDEFMessage(externalRecordMessageInit); 30 }, 'Creating a recursive NDEFMessage throws a TypeError'); 31 assert_throws_js(TypeError, () => { 32 new NDEFRecord(externalRecordMessageInit.records[0]); 33 }, 'Creating a recursive NDEFRecord throws a TypeError'); 34 assert_throws_js(TypeError, () => { 35 new NDEFReadingEvent('message', {message: externalRecordMessageInit}); 36 }, 'Creating a recursive NDEFReadingEvent throws a TypeError'); 37 }, 'NDEFRecord and NDEFMessage cycle in local records'); 38 39 test(() => { 40 let recordInit = {recordType: 'smart-poster'}; 41 const messageInit = { 42 records: [ 43 // Smart poster records require an URL record. Add it here so we can be 44 // sure a TypeError is being thrown because of the recursion limit, not 45 // the lack of a mandatory record. 46 {recordType: 'url', data: 'https://w3.org'}, recordInit 47 ] 48 }; 49 recordInit.data = messageInit; 50 51 assert_throws_js(TypeError, () => { 52 new NDEFMessage(messageInit); 53 }, 'Creating a recursive NDEFMessage throws a TypeError'); 54 assert_throws_js(TypeError, () => { 55 new NDEFRecord(recordInit); 56 }, 'Creating a recursive NDEFRecord throws a TypeError'); 57 assert_throws_js(TypeError, () => { 58 new NDEFReadingEvent('message', {message: messageInit}); 59 }, 'Creating a recursive NDEFReadingEvent throws a TypeError'); 60 }, 'NDEFRecord and NDEFMessage cycle in smart poster records'); 61 62 function makeSmartPosterMessageInit(innerMessageInit) { 63 const innerRecords = innerMessageInit.records; 64 return { 65 records: [{ 66 recordType: 'smart-poster', 67 data: { 68 records: 69 [{recordType: 'url', data: 'https://w3.org'}].concat(innerRecords) 70 } 71 }] 72 }; 73 } 74 75 // Creates an NDEFMessageInit with nested records except for the innermost 76 // one, which is an empty record. 77 function makeRecursiveMessageInit(innerRecordType, maxDepth) { 78 function innerHelper(value) { 79 if (++value > maxDepth) { 80 return {records: [{recordType: 'empty'}]}; 81 } 82 83 return {records: [{recordType: innerRecordType, data: innerHelper(value)}]}; 84 } 85 86 return innerHelper(0); 87 } 88 89 // Maximum number of chained NDEFMessages according to the spec. 90 const MAX_NESTING_LEVEL = 32; 91 92 test(() => { 93 // makeRecursiveMessageInit(..., N) will cause N NDEFMessages to be created 94 // when it is parsed. The calls are passed to an outer NDEFMessage 95 // constructor, so we end up with N+1 NDEFMessage objects. The spec allows 96 // up to 32 NDEFMessages in the same chain, and we have 33 here. 97 assert_throws_js(TypeError, () => { 98 new NDEFMessage( 99 makeRecursiveMessageInit('w3.org:ExternalRecord', MAX_NESTING_LEVEL)); 100 }, 'Creating a recursive NDEFMessage throws a TypeError'); 101 assert_throws_js(TypeError, () => { 102 new NDEFReadingEvent('message', { 103 message: 104 makeRecursiveMessageInit('w3.org:ExternalRecord', MAX_NESTING_LEVEL) 105 }); 106 }, 'Creating a recursive NDEFReadingEvent throws a TypeError'); 107 108 // Here we call makeRecursiveMessageInit() with a smaller number than above 109 // because there is a smart poster wrapping everything that also creates an 110 // NDEFMessage. 111 assert_throws_js(TypeError, () => { 112 const innerMessageInit = makeRecursiveMessageInit( 113 'w3.org:ExternalRecord', MAX_NESTING_LEVEL - 1); 114 new NDEFMessage(makeSmartPosterMessageInit(innerMessageInit)); 115 }, 'Creating a recursive NDEFMessage throws a TypeError'); 116 assert_throws_js(TypeError, () => { 117 const innerMessageInit = 118 makeRecursiveMessageInit(':local', MAX_NESTING_LEVEL - 1); 119 new NDEFMessage(makeSmartPosterMessageInit(innerMessageInit)); 120 }, 'Creating a recursive NDEFMessage throws a TypeError'); 121 assert_throws_js(TypeError, () => { 122 const innerMessageInit = makeRecursiveMessageInit( 123 'w3.org:ExternalRecord', MAX_NESTING_LEVEL - 1); 124 new NDEFReadingEvent( 125 'message', {message: makeSmartPosterMessageInit(innerMessageInit)}); 126 }, 'Creating a recursive NDEFMessage throws a TypeError'); 127 assert_throws_js(TypeError, () => { 128 const innerMessageInit = 129 makeRecursiveMessageInit(':local', MAX_NESTING_LEVEL - 1); 130 new NDEFReadingEvent( 131 'message', {message: makeSmartPosterMessageInit(innerMessageInit)}); 132 }, 'Creating a recursive NDEFMessage throws a TypeError'); 133 }, 'Create too many nested NDEFMessages'); 134 135 // See above for explanations about the counts passed to 136 // makeRecursiveMessageInit(). 137 test(() => { 138 new NDEFMessage( 139 makeRecursiveMessageInit('w3.org:ExternalRecord', MAX_NESTING_LEVEL - 1)); 140 new NDEFReadingEvent('message', { 141 message: 142 makeRecursiveMessageInit('w3.org:ExternalRecord', MAX_NESTING_LEVEL - 1) 143 }); 144 145 let innerMessageInit; 146 147 innerMessageInit = 148 makeRecursiveMessageInit('w3.org:ExternalRecord', MAX_NESTING_LEVEL - 2); 149 new NDEFMessage(makeSmartPosterMessageInit(innerMessageInit)); 150 new NDEFReadingEvent( 151 'message', {message: makeSmartPosterMessageInit(innerMessageInit)}); 152 innerMessageInit = makeRecursiveMessageInit(':local', MAX_NESTING_LEVEL - 2); 153 new NDEFMessage(makeSmartPosterMessageInit(innerMessageInit)); 154 new NDEFReadingEvent( 155 'message', {message: makeSmartPosterMessageInit(innerMessageInit)}); 156 }, 'Nest maximum number of NDEFMessages')