Skip to content

DomAppendMovesNodeUnexpectedly ​

warning native off by default

Group: Probable bugs

Clone the node when preserving its existing parent. This inspection is disabled by default; enabling it selects the stated policy.

Example ​

php
<?php
$d=new DOMDocument(); $a=$d->createElement('a'); $b=$d->createElement('b'); $n=$d->createElement('n'); $a->appendChild($n); $b->appendChild($n);

Reported:

  • line 2: Clone the node when preserving its existing parent.

Detection ​

  • The same proven node is appended consecutively to distinct proven parents. Enabling establishes that both parents must retain a copy. An intervening explicit detachment or clone excludes the finding (E3); do not infer this policy from identifiers.
  • Resolve builtin functions, extension classes, constants and method receivers, including aliases and supported named arguments. Inspect reachable operations in one lexical scope with bounded local flow.
  • Emit one finding per violating operation. Never infer policy from names or comments. When the proof is inconclusive, nothing is reported.

Exceptions (no report) ​

  • Exclude shadowed or unresolved symbols, incomplete code, unknown required constants, ambiguous receiver identity and unsupported versions. Reassignment, escaping aliases, and unknown calls invalidate dependent flow facts.

  • Both @custos-ignore DomAppendMovesNodeUnexpectedly and @noinspection DomAppendMovesNodeUnexpectedly suppress this native rule.

  • E3. A call that executes on every path between the two appends counts as an explicit detachment when it is one of:

    • remove() or replaceWith(...) called on the node itself;
    • removeChild or replaceChild naming the node, positionally or through the child/node named arguments, on any receiver;
    • replaceChildren(...) called on the first parent;
    • removeChild or replaceChild called on the first parent with a removed child that is not proven to be another node. The removed child is proven distinct only when it and the appended node both resolve to different local allocation calls (DOMDocument::createElement, createElementNS, createTextNode, createComment, createCDATASection, createDocumentFragment, or cloneNode); $parent->firstChild and similar navigations are never proven distinct.

    The same calls on unrelated nodes or parents keep the finding, as does removing the first parent itself.

Fix ​

None. A safe repair requires choosing values, error handling, or application behavior.

PHP versions ​

Apply throughout PHP 5.3–8.5 only where the extension API and syntax exist. Do not flag API unavailability through this rule. Legacy DOM classes are the initial target; modern Dom namespace classes require independently established matching contracts.

Options ​

None. Use normal rule configuration to enable or disable the inspection.

Configure ​

In custos.json:

json
{
  "rules": {
    "DomAppendMovesNodeUnexpectedly": {
      "enabled": true
    }
  }
}

Suppress ​

Before the statement or declaration (or the first statement of the file):

php
// @custos-ignore DomAppendMovesNodeUnexpectedly

Released under the MIT License. Native rules and rules modeled on Php Inspections (EA Extended); independent clean-room implementation.