<!DOCTYPE html>
<script>
if (window.testRunner) {
  testRunner.dumpAsText();
  testRunner.waitUntilDone();
  window.onload = function() {
    testRunner.display();
    mutateTree();
    testRunner.display();
    testRunner.notifyDone();
  };
} else {
  window.onload = function() { setTimeout(mutateTree, 100); };
}
const svgNs = 'http://www.w3.org/2000/svg';
function buildPattern(patternId, refId) {
  var pattern = document.createElementNS(svgNs, 'pattern');
  var rect = pattern.appendChild(document.createElementNS(svgNs, 'rect'));
  pattern.setAttribute('id', patternId);
  pattern.setAttribute('width', 1);
  pattern.setAttribute('height', 1);
  rect.setAttribute('width', 100);
  rect.setAttribute('height', 100);
  rect.setAttribute('fill', 'url(#' + refId + ')');
  return pattern;
}
function mutateTree() {
  // Build a three-step pattern cycle in a detached
  // subtree and then insert it at load.
  var defs = document.createElementNS(svgNs, 'defs');
  defs.appendChild(buildPattern('p3', 'p1'));
  defs.appendChild(buildPattern('p2', 'p3'));
  defs.appendChild(buildPattern('p1', 'p2'));
  document.querySelector('svg').appendChild(defs);
}
</script>
<p>PASS if no crash (stack overflow).</p>
<svg width="100" height="100">
  <rect width="100" height="100" fill="url(#p1)"/>
</svg>
