parsedepth.html (1825B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title></title> 4 <script src=/resources/testharness.js></script> 5 <script src=/resources/testharnessreport.js></script> 6 <script> 7 8 function parseBlob(blob) { 9 return new Promise(resolve => { 10 let xhr = new XMLHttpRequest(); 11 xhr.open("GET", URL.createObjectURL(blob)); 12 xhr.onload = () => { 13 resolve(xhr.responseXML); 14 } 15 xhr.send(); 16 }); 17 } 18 19 promise_test(async (t) => { 20 // Most browser engines, including Gecko, use 5000 as the limit, so test a 21 // range around that. 22 const cutoff = 5000; 23 24 let minDepth = cutoff - 100; 25 let maxDepth = cutoff + 100; 26 27 // Generate a string with elements nested maxDepth deep. 28 const openTag = "<x>"; 29 const closeTag = "</x>"; 30 let xml = openTag.repeat(maxDepth) + closeTag.repeat(maxDepth); 31 32 // Compute where we change from opening to closing tags. 33 const middle = maxDepth * openTag.length; 34 35 // Create a blob around the string. 36 let blob = new Blob([xml], { type: "application/xml" }); 37 38 while (minDepth < maxDepth) { 39 // Try to parse a number of nested tags between minDepth and maxDepth. 40 let test = Math.ceil((minDepth + maxDepth) / 2); 41 42 // We need the number of opening and closing tags to be equal to the number 43 // that we calculated above. 44 let slice = blob.slice(middle - (test * openTag.length), 45 middle + (test * closeTag.length), blob.type); 46 47 let responseXML = await parseBlob(slice); 48 49 // Move either minDepth or maxDepth so that the actual limit is still in the 50 // range of [minDepth-maxDepth]. 51 if (responseXML) { 52 // Depth is ok. 53 minDepth = test; 54 } else { 55 maxDepth = test - 1; 56 } 57 } 58 assert_equals(minDepth, maxDepth); 59 assert_equals(minDepth, cutoff); 60 },"Parsing XML fails when the nesting depth is 5000"); 61 62 </script>