tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_bug1995614_atomized_attributes.html (23721B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Test for Bug 1995614 - Single digit attribute atomization</title>
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
      8 </head>
      9 <body>
     10 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1995614">Mozilla Bug 1995614</a>
     11 <p id="display"></p>
     12 <div id="content" style="display: none">
     13 </div>
     14 <pre id="test">
     15 <script type="application/javascript">
     16 
     17 SimpleTest.waitForExplicitFinish();
     18 
     19 function testBasicHTMLElements(container) {
     20  let passed = 0;
     21 
     22  // Test 1: HTMLLinkElement with all possible single digit attributes
     23  try {
     24    container.innerHTML = '<link href="1" rel="2" type="3" media="4" hreflang="5" as="6" crossorigin="7" ' +
     25      'referrerpolicy="8" integrity="9" sizes="0" fetchpriority="1" blocking="2" class="3" id="4" ' +
     26      'title="5" lang="6" dir="7" nonce="8">';
     27    ok(true, "HTMLLinkElement with all single digit attributes doesn't crash");
     28    passed++;
     29  } catch (e) {
     30    ok(false, "HTMLLinkElement crashed: " + e);
     31  }
     32 
     33  // Test 2: HTMLSourceElement with all possible single digit attributes
     34  try {
     35    container.innerHTML = '<picture>' +
     36      '<source srcset="2" media="3" src="4" type="5" sizes="6" width="7" height="8" class="9" id="0" ' +
     37      'title="1" lang="2" dir="3">' +
     38      '<img src="5"></picture>';
     39    ok(true, "HTMLSourceElement with all single digit attributes doesn't crash");
     40    passed++;
     41  } catch (e) {
     42    ok(false, "HTMLSourceElement crashed: " + e);
     43  }
     44 
     45  // Test 3: HTMLInputElement with extensive single digit attributes
     46  try {
     47    container.innerHTML = '<input type="image" src="6" alt="7" width="8" height="9" ' +
     48      'name="0" value="1" placeholder="2" autocomplete="3" ' +
     49      'maxlength="4" minlength="5" size="6" pattern="7" ' +
     50      'min="8" max="9" step="0" list="1" ' +
     51      'dirname="2" form="3" formaction="4" formmethod="5" formtarget="6" formenctype="7" ' +
     52      'accept="8" multiple="9" readonly="0" disabled="1" required="2" ' +
     53      'inputmode="3" enterkeyhint="4" autocorrect="5" autocapitalize="6" spellcheck="7" ' +
     54      'class="8" id="9" title="0" lang="1" dir="2" tabindex="3" accesskey="4">';
     55    ok(true, "HTMLInputElement with extensive single digit attributes doesn't crash");
     56    passed++;
     57  } catch (e) {
     58    ok(false, "HTMLInputElement crashed: " + e);
     59  }
     60 
     61  // Test 4: HTMLScriptElement with all possible single digit attributes
     62  try {
     63    container.innerHTML = '<script src="7" type="8" async="9" defer="0" crossorigin="1" ' +
     64      'integrity="2" referrerpolicy="3" nonce="4" nomodule="5" fetchpriority="6" blocking="7" ' +
     65      'class="8" id="9"></' + 'script>';
     66    ok(true, "HTMLScriptElement with all single digit attributes doesn't crash");
     67    passed++;
     68  } catch (e) {
     69    ok(false, "HTMLScriptElement crashed: " + e);
     70  }
     71 
     72  // Test 5: HTMLButtonElement with all possible single digit attributes
     73  try {
     74    container.innerHTML = '<button command="8" commandfor="9" type="0" name="1" value="2" ' +
     75      'form="3" formaction="4" formmethod="5" formtarget="6" formenctype="7" formnovalidate="8" ' +
     76      'popovertarget="9" popovertargetaction="0" disabled="1" autofocus="2" ' +
     77      'class="3" id="4" title="5" tabindex="6" accesskey="7">Test</button>';
     78    ok(true, "HTMLButtonElement with all single digit attributes doesn't crash");
     79    passed++;
     80  } catch (e) {
     81    ok(false, "HTMLButtonElement crashed: " + e);
     82  }
     83 
     84  // Test 6: HTMLMediaElement (audio/video) with all possible single digit attributes
     85  try {
     86    container.innerHTML = '<audio src="1" preload="2" controls="3" autoplay="4" loop="5" muted="6" ' +
     87      'crossorigin="7" volume="8" class="9" id="0"></audio>' +
     88      '<video src="1" poster="2" width="3" height="4" preload="5" controls="6" autoplay="7" ' +
     89      'loop="8" muted="9" crossorigin="0" playsinline="1" disablepictureinpicture="2" ' +
     90      'class="3" id="4" title="5"></video>';
     91    ok(true, "HTMLMediaElement with all single digit attributes doesn't crash");
     92    passed++;
     93  } catch (e) {
     94    ok(false, "HTMLMediaElement crashed: " + e);
     95  }
     96 
     97  return passed;
     98 }
     99 
    100 function testSpecificAttributes(container) {
    101  let passed = 0;
    102 
    103  // Test 7: Elements with nonce attribute
    104  try {
    105    container.innerHTML = '<div nonce="9">Test</div><script nonce="1"></' + 'script>';
    106    ok(true, "Elements with single digit nonce don't crash");
    107    passed++;
    108  } catch (e) {
    109    ok(false, "Nonce attribute crashed: " + e);
    110  }
    111 
    112  // Test 8: class attribute (specifically atomized)
    113  try {
    114    container.innerHTML = '<div class="1">A</div><span class="2">B</span>';
    115    ok(true, "Elements with single digit class don't crash");
    116    passed++;
    117  } catch (e) {
    118    ok(false, "Class attribute crashed: " + e);
    119  }
    120 
    121  // Test 9: type attribute (specifically atomized)
    122  try {
    123    container.innerHTML = '<input type="3"><button type="4">Test</button>';
    124    ok(true, "Elements with single digit type don't crash");
    125    passed++;
    126  } catch (e) {
    127    ok(false, "Type attribute crashed: " + e);
    128  }
    129 
    130  // Test 10: Dynamic attribute setting
    131  try {
    132    let link = document.createElement("link");
    133    link.setAttribute("href", "5");
    134    container.appendChild(link);
    135    ok(true, "Dynamic setAttribute with single digit doesn't crash");
    136    passed++;
    137  } catch (e) {
    138    ok(false, "Dynamic setAttribute crashed: " + e);
    139  }
    140 
    141  // Test 11: Event handlers
    142  try {
    143    let div = document.createElement("div");
    144    div.setAttribute("onclick", "console.log('test')");
    145    container.appendChild(div);
    146    ok(true, "Event handler attribute doesn't crash");
    147    passed++;
    148  } catch (e) {
    149    ok(false, "Event handler crashed: " + e);
    150  }
    151 
    152  return passed;
    153 }
    154 
    155 function testFormElements(container) {
    156  let passed = 0;
    157 
    158  // Test 12: HTMLFontElement with all possible single digit attributes
    159  try {
    160    container.innerHTML = '<font face="6" size="7" color="8" class="9" id="0" ' +
    161      'title="1" lang="2" dir="3">Test</font>';
    162    ok(true, "HTMLFontElement with all single digit attributes doesn't crash");
    163    passed++;
    164  } catch (e) {
    165    ok(false, "HTMLFontElement crashed: " + e);
    166  }
    167 
    168  // Test 12a: HTMLFrameSetElement with all possible single digit attributes
    169  try {
    170    container.innerHTML = '<frameset rows="1" cols="2" border="3" bordercolor="4" ' +
    171      'frameborder="5" framespacing="6" class="7" id="8">' +
    172      '<frame src="9" name="0" scrolling="1" noresize="2" marginwidth="3" marginheight="4" ' +
    173      'frameborder="5" bordercolor="6" longdesc="7">' +
    174      '</frameset>';
    175    ok(true, "HTMLFrameSetElement with all single digit attributes doesn't crash");
    176    passed++;
    177  } catch (e) {
    178    ok(false, "HTMLFrameSetElement crashed: " + e);
    179  }
    180 
    181  // Test 12b: Textarea with all possible single digit attributes
    182  try {
    183    container.innerHTML = '<textarea name="8" rows="9" cols="0" wrap="1" maxlength="2" minlength="3" ' +
    184      'placeholder="4" form="5" dirname="6" readonly="7" disabled="8" required="9" ' +
    185      'autocomplete="0" inputmode="1" spellcheck="2" autocorrect="3" autocapitalize="4" ' +
    186      'class="5" id="6" tabindex="7">Text</textarea>';
    187    ok(true, "Textarea with all single digit attributes doesn't crash");
    188    passed++;
    189  } catch (e) {
    190    ok(false, "Textarea crashed: " + e);
    191  }
    192 
    193  // Test 12c: Select and option with all possible attributes
    194  try {
    195    container.innerHTML = '<select name="8" size="9" form="0" autocomplete="1" multiple="2" ' +
    196      'disabled="3" required="4" autofocus="5" class="6" id="7">' +
    197      '<option value="8" selected="9" disabled="0" label="1" class="2">A</option>' +
    198      '<option value="3" class="4">B</option>' +
    199      '<optgroup label="5" disabled="6" class="7">' +
    200      '<option value="8">C</option>' +
    201      '</optgroup>' +
    202      '</select>';
    203    ok(true, "Select/option with all single digit attributes don't crash");
    204    passed++;
    205  } catch (e) {
    206    ok(false, "Select/option crashed: " + e);
    207  }
    208 
    209  // Test 12d: Form elements (label, fieldset, output, progress, meter)
    210  try {
    211    container.innerHTML = '<form action="9" method="0" name="1" target="2" autocomplete="3" ' +
    212      'enctype="4" accept-charset="5" novalidate="6" class="7" id="8">' +
    213      '<label for="9" form="0" class="1">Label</label>' +
    214      '<fieldset name="2" form="3" disabled="4" class="5"><legend>6</legend></fieldset>' +
    215      '<output name="7" for="8" form="9" class="0">Output</output>' +
    216      '<progress value="1" max="2" class="3">4</progress>' +
    217      '<meter value="5" min="6" max="7" low="8" high="9" optimum="0" class="1">2</meter>' +
    218      '</form>';
    219    ok(true, "Form/label/fieldset/output/progress/meter with single digits don't crash");
    220    passed++;
    221  } catch (e) {
    222    ok(false, "Form elements crashed: " + e);
    223  }
    224 
    225  // Test 12e: Details and dialog
    226  try {
    227    container.innerHTML = '<details name="3" open="4" class="5"><summary class="6">7</summary>8</details>' +
    228      '<dialog open="9" class="0">1</dialog>';
    229    ok(true, "Details/dialog with single digit attributes don't crash");
    230    passed++;
    231  } catch (e) {
    232    ok(false, "Details/dialog crashed: " + e);
    233  }
    234 
    235  return passed;
    236 }
    237 
    238 function testARIAAndDataAttributes(container) {
    239  let passed = 0;
    240 
    241  // Test 13: ARIA attributes with single digits
    242  try {
    243    container.innerHTML = `
    244      <div role="1" aria-label="2" aria-describedby="3" aria-labelledby="4" aria-controls="5">A</div>
    245      <div aria-hidden="6" aria-live="7" aria-atomic="8" aria-busy="9" aria-disabled="0">B</div>
    246      <div aria-checked="1" aria-pressed="2" aria-selected="3" aria-expanded="4" aria-level="5">C</div>
    247      <div aria-valuemin="6" aria-valuemax="7" aria-valuenow="8" aria-valuetext="9">D</div>
    248      <div aria-colcount="0" aria-colindex="1" aria-colspan="2" aria-rowcount="3" aria-rowindex="4" aria-rowspan="5">E</div>
    249      <div aria-posinset="6" aria-setsize="7" aria-owns="8" aria-activedescendant="9">F</div>
    250    `;
    251    ok(true, "ARIA attributes with single digits don't crash");
    252    passed++;
    253  } catch (e) {
    254    ok(false, "ARIA attributes crashed: " + e);
    255  }
    256 
    257  // Test 14: data-* attributes with single digits
    258  try {
    259    container.innerHTML = `
    260      <div data-id="1" data-value="2" data-index="3" data-count="4" data-level="5">A</div>
    261      <div data-priority="6" data-size="7" data-width="8" data-height="9">B</div>
    262      <div data-0="0" data-1="1" data-2="2" data-3="3">C</div>
    263    `;
    264    ok(true, "data-* attributes with single digits don't crash");
    265    passed++;
    266  } catch (e) {
    267    ok(false, "data-* attributes crashed: " + e);
    268  }
    269 
    270  // Test 15: Global attributes with single digits
    271  try {
    272    container.innerHTML = `
    273      <div id="4" title="5" lang="6" dir="7" tabindex="8" accesskey="9">A</div>
    274      <div contenteditable="0" spellcheck="1" translate="2" hidden="3" draggable="4">B</div>
    275      <div enterkeyhint="5" inputmode="6" autocapitalize="7" autocorrect="8">C</div>
    276    `;
    277    ok(true, "Global attributes with single digits don't crash");
    278    passed++;
    279  } catch (e) {
    280    ok(false, "Global attributes crashed: " + e);
    281  }
    282 
    283  // Test 16: Microdata attributes with single digits
    284  try {
    285    container.innerHTML = `
    286      <div itemscope itemtype="1" itemprop="2" itemid="3" itemref="4">A</div>
    287      <div itemprop="5">B</div>
    288    `;
    289    ok(true, "Microdata attributes with single digits don't crash");
    290    passed++;
    291  } catch (e) {
    292    ok(false, "Microdata attributes crashed: " + e);
    293  }
    294 
    295  return passed;
    296 }
    297 
    298 function testResourceAndLayoutAttributes(container) {
    299  let passed = 0;
    300 
    301  // Test 17: Form-related attributes with single digits
    302  try {
    303    container.innerHTML = `
    304      <input name="1" value="2" placeholder="3" pattern="4" maxlength="5" minlength="6">
    305      <input min="7" max="8" step="9" size="0">
    306      <textarea rows="1" cols="2" maxlength="3" minlength="4">5</textarea>
    307      <select name="6" size="7"><option value="8">9</option></select>
    308    `;
    309    ok(true, "Form attributes with single digits don't crash");
    310    passed++;
    311  } catch (e) {
    312    ok(false, "Form attributes crashed: " + e);
    313  }
    314 
    315  // Test 18: Resource loading attributes with single digits
    316  try {
    317    container.innerHTML = '<img loading="1" decoding="2" fetchpriority="3" crossorigin="4" referrerpolicy="5" src="6">' +
    318      '<iframe loading="7" src="8"></iframe>' +
    319      '<link rel="preload" as="9" href="0" fetchpriority="1">' +
    320      '<script blocking="2" src="3"></' + 'script>';
    321    ok(true, "Resource loading attributes with single digits don't crash");
    322    passed++;
    323  } catch (e) {
    324    ok(false, "Resource loading attributes crashed: " + e);
    325  }
    326 
    327  // Test 19: Table attributes with single digits
    328  try {
    329    container.innerHTML = `
    330      <table border="1" cellpadding="2" cellspacing="3">
    331        <tr>
    332          <td colspan="4" rowspan="5" width="6" height="7" align="8" valign="9">A</td>
    333        </tr>
    334      </table>
    335    `;
    336    ok(true, "Table attributes with single digits don't crash");
    337    passed++;
    338  } catch (e) {
    339    ok(false, "Table attributes crashed: " + e);
    340  }
    341 
    342  // Test 20: List attributes with single digits
    343  try {
    344    container.innerHTML = `
    345      <ol type="0" start="1" reversed="2">
    346        <li value="3">A</li>
    347        <li value="4">B</li>
    348      </ol>
    349    `;
    350    ok(true, "List attributes with single digits don't crash");
    351    passed++;
    352  } catch (e) {
    353    ok(false, "List attributes crashed: " + e);
    354  }
    355 
    356  // Test 21: Link attributes with single digits
    357  try {
    358    container.innerHTML = `
    359      <a href="5" target="6" rel="7" hreflang="8" type="9" download="0" ping="1" referrerpolicy="2">Link</a>
    360      <area href="3" alt="4" coords="5" shape="6">
    361    `;
    362    ok(true, "Link attributes with single digits don't crash");
    363    passed++;
    364  } catch (e) {
    365    ok(false, "Link attributes crashed: " + e);
    366  }
    367 
    368  return passed;
    369 }
    370 
    371 function testMediaElements(container) {
    372  let passed = 0;
    373 
    374  // Test 22: Media attributes with single digits
    375  try {
    376    container.innerHTML = '<video width="7" height="8" poster="9" preload="0" controls="1" autoplay="2" loop="3" muted="4">' +
    377      '<source src="5" type="6" media="7">' +
    378      '<track kind="8" src="9" srclang="0" label="1" default="2">' +
    379      '</video>' +
    380      '<audio src="3" preload="4" controls="5" autoplay="6" loop="7" muted="8" crossorigin="9"></audio>';
    381    ok(true, "Media attributes with single digits don't crash");
    382    passed++;
    383  } catch (e) {
    384    ok(false, "Media attributes crashed: " + e);
    385  }
    386 
    387  // Test 22a: Picture element with srcset and sizes
    388  try {
    389    container.innerHTML = '<picture>' +
    390      '<source srcset="1" media="2" type="3" sizes="4" width="5" height="6">' +
    391      '<source srcset="7" media="8">' +
    392      '<img src="9" srcset="0" sizes="1" alt="2" width="3" height="4">' +
    393      '</picture>';
    394    ok(true, "Picture/source with srcset/sizes single digits don't crash");
    395    passed++;
    396  } catch (e) {
    397    ok(false, "Picture element crashed: " + e);
    398  }
    399 
    400  // Test 22b: Iframe with various attributes
    401  try {
    402    container.innerHTML = '<iframe src="5" srcdoc="6" name="7" width="8" height="9" sandbox="0" allow="1" loading="2" referrerpolicy="3"></iframe>';
    403    ok(true, "Iframe attributes with single digits don't crash");
    404    passed++;
    405  } catch (e) {
    406    ok(false, "Iframe attributes crashed: " + e);
    407  }
    408 
    409  // Test 22c: Embed and object elements
    410  try {
    411    container.innerHTML = '<embed src="4" type="5" width="6" height="7">' +
    412      '<object data="8" type="9" name="0" width="1" height="2" form="3">' +
    413      '<param name="4" value="5">' +
    414      '</object>';
    415    ok(true, "Embed/object attributes with single digits don't crash");
    416    passed++;
    417  } catch (e) {
    418    ok(false, "Embed/object crashed: " + e);
    419  }
    420 
    421  // Test 22d: Canvas element
    422  try {
    423    container.innerHTML = '<canvas width="6" height="7" class="8">9</canvas>';
    424    ok(true, "Canvas attributes with single digits don't crash");
    425    passed++;
    426  } catch (e) {
    427    ok(false, "Canvas crashed: " + e);
    428  }
    429 
    430  return passed;
    431 }
    432 
    433 function testModernHTMLFeatures(container) {
    434  let passed = 0;
    435 
    436  // Test 23: Popover and command attributes with single digits
    437  try {
    438    container.innerHTML = `
    439      <div popover="3" id="p1">Popover</div>
    440      <button popovertarget="4" popovertargetaction="5">Toggle</button>
    441      <button commandfor="6" command="7">Command</button>
    442    `;
    443    ok(true, "Popover and command attributes with single digits don't crash");
    444    passed++;
    445  } catch (e) {
    446    ok(false, "Popover/command attributes crashed: " + e);
    447  }
    448 
    449  // Test 24: Shadow DOM attributes with single digits
    450  try {
    451    container.innerHTML = `
    452      <div slot="8" part="9">Slotted</div>
    453      <template shadowrootmode="0">Shadow</template>
    454    `;
    455    ok(true, "Shadow DOM attributes with single digits don't crash");
    456    passed++;
    457  } catch (e) {
    458    ok(false, "Shadow DOM attributes crashed: " + e);
    459  }
    460 
    461  // Test 25: Deprecated element attributes with single digits
    462  try {
    463    container.innerHTML = '<marquee behavior="1" direction="2" scrollamount="3" scrolldelay="4" loop="5">Text</marquee>' +
    464      '<frameset rows="6" cols="7" border="8"></frameset>';
    465    ok(true, "Deprecated element attributes with single digits don't crash");
    466    passed++;
    467  } catch (e) {
    468    ok(false, "Deprecated element attributes crashed: " + e);
    469  }
    470 
    471  return passed;
    472 }
    473 
    474 function testSVGElements(container) {
    475  let passed = 0;
    476 
    477  // Test 26: SVGAnimationElement with single digit attributes
    478  try {
    479    container.innerHTML = '<svg><animate href="#t" attributeName="x" from="1" to="2" dur="3s"/></svg>';
    480    ok(true, "SVGAnimationElement with single digit href/from/to doesn't crash");
    481    passed++;
    482  } catch (e) {
    483    ok(false, "SVGAnimationElement crashed: " + e);
    484  }
    485 
    486  // Test 27: animateMotion with path attribute
    487  try {
    488    container.innerHTML = '<svg><animateMotion path="M 1 2 L 3 4" dur="5s"/></svg>';
    489    ok(true, "animateMotion with path containing digits doesn't crash");
    490    passed++;
    491  } catch (e) {
    492    ok(false, "animateMotion crashed: " + e);
    493  }
    494 
    495  // Test 28: animateMotion with values/by attributes
    496  try {
    497    container.innerHTML = '<svg><animateMotion values="1;2;3" dur="4s"/><animateMotion by="5" dur="6s"/></svg>';
    498    ok(true, "animateMotion with values/by containing digits doesn't crash");
    499    passed++;
    500  } catch (e) {
    501    ok(false, "animateMotion values/by crashed: " + e);
    502  }
    503 
    504  // Test 29: SVG elements with nonce and event handlers
    505  try {
    506    container.innerHTML = '<svg><rect nonce="7" onclick="console.log(\'8\')" class="9" width="10" height="10"/></svg>';
    507    ok(true, "SVG elements with single digit nonce/onclick/class don't crash");
    508    passed++;
    509  } catch (e) {
    510    ok(false, "SVG nonce/onclick/class crashed: " + e);
    511  }
    512 
    513  // Test 30: SVG with various single digit attributes
    514  try {
    515    container.innerHTML = `
    516      <svg width="1" height="2" viewBox="3">
    517        <rect x="4" y="5" width="6" height="7" fill="8" stroke="9" opacity="0"/>
    518        <circle cx="1" cy="2" r="3" class="4"/>
    519        <text x="5" y="6" font-size="7">Text</text>
    520        <use href="#8" x="9" y="0"/>
    521      </svg>
    522    `;
    523    ok(true, "SVG geometry attributes with single digits don't crash");
    524    passed++;
    525  } catch (e) {
    526    ok(false, "SVG geometry attributes crashed: " + e);
    527  }
    528 
    529  return passed;
    530 }
    531 
    532 function testMathMLElements(container) {
    533  let passed = 0;
    534 
    535  // Test 31: MathML elements with width attribute
    536  try {
    537    container.innerHTML = '<math><mspace width="1" height="2"/></math>';
    538    ok(true, "MathML mspace with single digit width/height doesn't crash");
    539    passed++;
    540  } catch (e) {
    541    ok(false, "MathML width/height crashed: " + e);
    542  }
    543 
    544  // Test 32: MathML scriptlevel attribute (commonly uses single digits)
    545  try {
    546    container.innerHTML = `
    547      <math>
    548        <mstyle scriptlevel="0"><mi>a</mi></mstyle>
    549        <mstyle scriptlevel="1"><mi>b</mi></mstyle>
    550        <mstyle scriptlevel="2"><mi>c</mi></mstyle>
    551        <mstyle scriptlevel="+1"><mi>d</mi></mstyle>
    552        <mstyle scriptlevel="-1"><mi>e</mi></mstyle>
    553      </math>
    554    `;
    555    ok(true, "MathML scriptlevel with single digits doesn't crash");
    556    passed++;
    557  } catch (e) {
    558    ok(false, "MathML scriptlevel crashed: " + e);
    559  }
    560 
    561  // Test 33: MathML mathsize and mathvariant
    562  try {
    563    container.innerHTML = `
    564      <math>
    565        <mstyle mathsize="3"><mi mathvariant="4">x</mi></mstyle>
    566        <mi mathvariant="5">y</mi>
    567      </math>
    568    `;
    569    ok(true, "MathML mathsize/mathvariant with single digits don't crash");
    570    passed++;
    571  } catch (e) {
    572    ok(false, "MathML mathsize/mathvariant crashed: " + e);
    573  }
    574 
    575  // Test 34: MathML dir, displaystyle, href
    576  try {
    577    container.innerHTML = '<math dir="6"><mstyle displaystyle="7"><mtext href="8">Link</mtext></mstyle></math>';
    578    ok(true, "MathML dir/displaystyle/href with single digits don't crash");
    579    passed++;
    580  } catch (e) {
    581    ok(false, "MathML dir/displaystyle/href crashed: " + e);
    582  }
    583 
    584  // Test 35: MathML event handlers, nonce, class
    585  try {
    586    container.innerHTML = '<math><mi onclick="console.log(\'9\')" nonce="0" class="1">x</mi></math>';
    587    ok(true, "MathML elements with onclick/nonce/class don't crash");
    588    passed++;
    589  } catch (e) {
    590    ok(false, "MathML onclick/nonce/class crashed: " + e);
    591  }
    592 
    593  return passed;
    594 }
    595 
    596 function testDigitCoverage(container) {
    597  let passed = 0;
    598 
    599  // Test 36: All single digits 0-9 with class attribute
    600  try {
    601    container.innerHTML = `
    602      <div class="0">0</div>
    603      <div class="1">1</div>
    604      <div class="2">2</div>
    605      <div class="3">3</div>
    606      <div class="4">4</div>
    607      <div class="5">5</div>
    608      <div class="6">6</div>
    609      <div class="7">7</div>
    610      <div class="8">8</div>
    611      <div class="9">9</div>
    612    `;
    613    ok(true, "All single digits 0-9 as class values don't crash");
    614    passed++;
    615  } catch (e) {
    616    ok(false, "Digits 0-9 crashed: " + e);
    617  }
    618 
    619  // Test 37: All single digits 0-9 with type attribute
    620  try {
    621    container.innerHTML = '<input type="0">' +
    622      '<input type="1">' +
    623      '<input type="2">' +
    624      '<input type="3">' +
    625      '<button type="4">A</button>' +
    626      '<button type="5">B</button>' +
    627      '<link type="6" href="test">' +
    628      '<script type="7"></' + 'script>' +
    629      '<style type="8"></style>';
    630    ok(true, "All single digits with type attribute don't crash");
    631    passed++;
    632  } catch (e) {
    633    ok(false, "Type attribute digits crashed: " + e);
    634  }
    635 
    636  // Test 38: Re-parsing via innerHTML (original crash scenario)
    637  try {
    638    let tempDiv = document.createElement("div");
    639    tempDiv.innerHTML = `
    640      <link href="1">
    641      <source srcset="2">
    642      <input type="image" src="3">
    643      <svg><animate href="#x" from="4" to="5"/></svg>
    644      <math><mstyle scriptlevel="6" mathsize="7"><mi>x</mi></mstyle></math>
    645    `;
    646    container.appendChild(tempDiv);
    647    // eslint-disable-next-line no-self-assign
    648    container.innerHTML = container.innerHTML;
    649    ok(true, "Re-parsing innerHTML with atomized attributes doesn't crash");
    650    passed++;
    651  } catch (e) {
    652    ok(false, "Re-parsing innerHTML crashed: " + e);
    653  }
    654 
    655  return passed;
    656 }
    657 
    658 function runTests() {
    659  let container = document.getElementById("content");
    660  let testsPassed = 0;
    661 
    662  testsPassed += testBasicHTMLElements(container);
    663  testsPassed += testSpecificAttributes(container);
    664  testsPassed += testFormElements(container);
    665  testsPassed += testARIAAndDataAttributes(container);
    666  testsPassed += testResourceAndLayoutAttributes(container);
    667  testsPassed += testMediaElements(container);
    668  testsPassed += testModernHTMLFeatures(container);
    669  testsPassed += testSVGElements(container);
    670  testsPassed += testMathMLElements(container);
    671  testsPassed += testDigitCoverage(container);
    672 
    673  is(testsPassed, 47, "All 47 atomization tests passed");
    674  SimpleTest.finish();
    675 }
    676 
    677 addLoadEvent(runTests);
    678 
    679 </script>
    680 </pre>
    681 </body>
    682 </html>