@@ -1490,33 +1490,58 @@ static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other
1490
1490
1491
1491
#define PHP_DOM_FUNC_CAT (prefix , suffix ) prefix##_##suffix
1492
1492
/* xmlNode and xmlNs have incompatible struct layouts, i.e. the next field is in a different offset */
1493
- #define PHP_DOM_DEFINE_LIST_EQUALITY_HELPER (type ) \
1494
- static size_t PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(const type *node) \
1495
- { \
1496
- size_t counter = 0; \
1497
- while (node) { \
1498
- counter++; \
1499
- node = node->next; \
1500
- } \
1501
- return counter; \
1502
- } \
1503
- static bool PHP_DOM_FUNC_CAT(php_dom_node_list_equality_check, type)(const type *list1, const type *list2) \
1504
- { \
1505
- size_t count = PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list1); \
1506
- if (count != PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list2)) { \
1507
- return false; \
1508
- } \
1509
- for (size_t i = 0; i < count; i++) { \
1510
- if (!php_dom_node_is_equal_node((const xmlNode *) list1, (const xmlNode *) list2)) { \
1511
- return false; \
1512
- } \
1513
- list1 = list1->next; \
1514
- list2 = list2->next; \
1515
- } \
1516
- return true; \
1517
- }
1518
- PHP_DOM_DEFINE_LIST_EQUALITY_HELPER (xmlNode )
1519
- PHP_DOM_DEFINE_LIST_EQUALITY_HELPER (xmlNs )
1493
+ #define PHP_DOM_DEFINE_LIST_COUNTER_HELPER (type ) \
1494
+ static size_t PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(const type *node) \
1495
+ { \
1496
+ size_t counter = 0; \
1497
+ while (node) { \
1498
+ counter++; \
1499
+ node = node->next; \
1500
+ } \
1501
+ return counter; \
1502
+ }
1503
+ #define PHP_DOM_DEFINE_LIST_EQUALITY_ORDERED_HELPER (type ) \
1504
+ static bool PHP_DOM_FUNC_CAT(php_dom_node_list_equality_check_ordered, type)(const type *list1, const type *list2) \
1505
+ { \
1506
+ size_t count = PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list1); \
1507
+ if (count != PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list2)) { \
1508
+ return false; \
1509
+ } \
1510
+ for (size_t i = 0; i < count; i++) { \
1511
+ if (!php_dom_node_is_equal_node((const xmlNode *) list1, (const xmlNode *) list2)) { \
1512
+ return false; \
1513
+ } \
1514
+ list1 = list1->next; \
1515
+ list2 = list2->next; \
1516
+ } \
1517
+ return true; \
1518
+ }
1519
+ #define PHP_DOM_DEFINE_LIST_EQUALITY_UNORDERED_HELPER (type ) \
1520
+ static bool PHP_DOM_FUNC_CAT(php_dom_node_list_equality_check_unordered, type)(const type *list1, const type *list2)\
1521
+ { \
1522
+ size_t count = PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list1); \
1523
+ if (count != PHP_DOM_FUNC_CAT(php_dom_node_count_list_size, type)(list2)) { \
1524
+ return false; \
1525
+ } \
1526
+ for (const type *n1 = list1; n1 != NULL; n1 = n1->next) { \
1527
+ bool found = false; \
1528
+ for (const type *n2 = list2; n2 != NULL && !found; n2 = n2->next) { \
1529
+ if (php_dom_node_is_equal_node((const xmlNode *) n1, (const xmlNode *) n2)) { \
1530
+ found = true; \
1531
+ } \
1532
+ } \
1533
+ if (!found) { \
1534
+ return false; \
1535
+ } \
1536
+ } \
1537
+ return true; \
1538
+ }
1539
+
1540
+ PHP_DOM_DEFINE_LIST_COUNTER_HELPER (xmlNode )
1541
+ PHP_DOM_DEFINE_LIST_COUNTER_HELPER (xmlNs )
1542
+ PHP_DOM_DEFINE_LIST_EQUALITY_ORDERED_HELPER (xmlNode )
1543
+ PHP_DOM_DEFINE_LIST_EQUALITY_UNORDERED_HELPER (xmlNode )
1544
+ PHP_DOM_DEFINE_LIST_EQUALITY_UNORDERED_HELPER (xmlNs )
1520
1545
1521
1546
static bool php_dom_node_is_equal_node (const xmlNode * this , const xmlNode * other )
1522
1547
{
@@ -1535,9 +1560,9 @@ static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other
1535
1560
&& php_dom_node_is_ns_prefix_equal (this , other )
1536
1561
&& php_dom_node_is_ns_uri_equal (this , other )
1537
1562
/* Check attributes first, then namespace declarations, then children */
1538
- && php_dom_node_list_equality_check_xmlNode ((const xmlNode * ) this -> properties , (const xmlNode * ) other -> properties )
1539
- && php_dom_node_list_equality_check_xmlNs (this -> nsDef , other -> nsDef )
1540
- && php_dom_node_list_equality_check_xmlNode (this -> children , other -> children );
1563
+ && php_dom_node_list_equality_check_unordered_xmlNode ((const xmlNode * ) this -> properties , (const xmlNode * ) other -> properties )
1564
+ && php_dom_node_list_equality_check_unordered_xmlNs (this -> nsDef , other -> nsDef )
1565
+ && php_dom_node_list_equality_check_ordered_xmlNode (this -> children , other -> children );
1541
1566
} else if (this -> type == XML_DTD_NODE ) {
1542
1567
/* Note: in the living spec entity declarations and notations are no longer compared because they're considered obsolete. */
1543
1568
const xmlDtd * this_dtd = (const xmlDtd * ) this ;
@@ -1570,7 +1595,7 @@ static bool php_dom_node_is_equal_node(const xmlNode *this, const xmlNode *other
1570
1595
const xmlNs * other_ns = (const xmlNs * ) other ;
1571
1596
return xmlStrEqual (this_ns -> prefix , other_ns -> prefix ) && xmlStrEqual (this_ns -> href , other_ns -> href );
1572
1597
} else if (this -> type == XML_DOCUMENT_FRAG_NODE || this -> type == XML_HTML_DOCUMENT_NODE || this -> type == XML_DOCUMENT_NODE ) {
1573
- return php_dom_node_list_equality_check_xmlNode (this -> children , other -> children );
1598
+ return php_dom_node_list_equality_check_ordered_xmlNode (this -> children , other -> children );
1574
1599
}
1575
1600
1576
1601
return false;
0 commit comments