|
| 1 | +--TEST-- |
| 2 | +GH-22825 (DOMElement::setAttribute() reaches EMPTY_SWITCH_DEFAULT_CASE() with DTD #FIXED default attributes) |
| 3 | +--EXTENSIONS-- |
| 4 | +dom |
| 5 | +--FILE-- |
| 6 | +<?php |
| 7 | +$cases = [ |
| 8 | + ['<!ATTLIST root A CDATA #FIXED "d">', '<root/>', 'A'], |
| 9 | + ['<!ATTLIST root A CDATA "d">', '<root/>', 'A'], |
| 10 | + ['<!ATTLIST root p:A CDATA #FIXED "d">', '<root xmlns:p="urn:p"/>', 'p:A'], |
| 11 | +]; |
| 12 | + |
| 13 | +function element(string $attlist, string $root): DOMElement { |
| 14 | + $doc = new DOMDocument(); |
| 15 | + $doc->loadXML("<!DOCTYPE root [$attlist]>$root"); |
| 16 | + return $doc->documentElement; |
| 17 | +} |
| 18 | + |
| 19 | +foreach ($cases as [$attlist, $root, $name]) { |
| 20 | + echo "--- $attlist ---\n"; |
| 21 | + |
| 22 | + $el = element($attlist, $root); |
| 23 | + echo "hasAttribute: "; |
| 24 | + var_dump($el->hasAttribute($name)); |
| 25 | + echo "getAttribute: "; |
| 26 | + var_dump($el->getAttribute($name)); |
| 27 | + |
| 28 | + $el = element($attlist, $root); |
| 29 | + $result = $el->setAttribute($name, 'v'); |
| 30 | + echo "setAttribute: ", is_object($result) ? $result::class : var_export($result, true), "\n"; |
| 31 | + echo "after setAttribute: ", trim($el->ownerDocument->saveXML($el)), "\n"; |
| 32 | + |
| 33 | + $el = element($attlist, $root); |
| 34 | + echo "removeAttribute: "; |
| 35 | + var_dump($el->removeAttribute($name)); |
| 36 | + echo "still present after removeAttribute: "; |
| 37 | + var_dump($el->hasAttribute($name)); |
| 38 | + |
| 39 | + $el = element($attlist, $root); |
| 40 | + echo "toggleAttribute(false): "; |
| 41 | + var_dump($el->toggleAttribute($name, false)); |
| 42 | + echo "still present after toggleAttribute(false): "; |
| 43 | + var_dump($el->hasAttribute($name)); |
| 44 | + |
| 45 | + $el = element($attlist, $root); |
| 46 | + echo "toggleAttribute(true): "; |
| 47 | + var_dump($el->toggleAttribute($name, true)); |
| 48 | + echo "still present after toggleAttribute(true): "; |
| 49 | + var_dump($el->hasAttribute($name)); |
| 50 | + |
| 51 | + $el = element($attlist, $root); |
| 52 | + $attr = $el->ownerDocument->createAttribute($name); |
| 53 | + $attr->value = 'z'; |
| 54 | + echo "setAttributeNode: "; |
| 55 | + var_dump($el->setAttributeNode($attr)); |
| 56 | + echo "after setAttributeNode: ", trim($el->ownerDocument->saveXML($el)), "\n"; |
| 57 | +} |
| 58 | +?> |
| 59 | +--EXPECT-- |
| 60 | +--- <!ATTLIST root A CDATA #FIXED "d"> --- |
| 61 | +hasAttribute: bool(true) |
| 62 | +getAttribute: string(1) "d" |
| 63 | +setAttribute: DOMAttr |
| 64 | +after setAttribute: <root A="v"/> |
| 65 | +removeAttribute: bool(false) |
| 66 | +still present after removeAttribute: bool(true) |
| 67 | +toggleAttribute(false): bool(true) |
| 68 | +still present after toggleAttribute(false): bool(true) |
| 69 | +toggleAttribute(true): bool(true) |
| 70 | +still present after toggleAttribute(true): bool(true) |
| 71 | +setAttributeNode: NULL |
| 72 | +after setAttributeNode: <root A="z"/> |
| 73 | +--- <!ATTLIST root A CDATA "d"> --- |
| 74 | +hasAttribute: bool(true) |
| 75 | +getAttribute: string(1) "d" |
| 76 | +setAttribute: DOMAttr |
| 77 | +after setAttribute: <root A="v"/> |
| 78 | +removeAttribute: bool(false) |
| 79 | +still present after removeAttribute: bool(true) |
| 80 | +toggleAttribute(false): bool(true) |
| 81 | +still present after toggleAttribute(false): bool(true) |
| 82 | +toggleAttribute(true): bool(true) |
| 83 | +still present after toggleAttribute(true): bool(true) |
| 84 | +setAttributeNode: NULL |
| 85 | +after setAttributeNode: <root A="z"/> |
| 86 | +--- <!ATTLIST root p:A CDATA #FIXED "d"> --- |
| 87 | +hasAttribute: bool(true) |
| 88 | +getAttribute: string(1) "d" |
| 89 | +setAttribute: DOMAttr |
| 90 | +after setAttribute: <root xmlns:p="urn:p" p:A="v"/> |
| 91 | +removeAttribute: bool(false) |
| 92 | +still present after removeAttribute: bool(true) |
| 93 | +toggleAttribute(false): bool(true) |
| 94 | +still present after toggleAttribute(false): bool(true) |
| 95 | +toggleAttribute(true): bool(true) |
| 96 | +still present after toggleAttribute(true): bool(true) |
| 97 | +setAttributeNode: NULL |
| 98 | +after setAttributeNode: <root xmlns:p="urn:p" p:A="z"/> |
0 commit comments