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