@@ -1396,40 +1396,52 @@ mark_attr_diff(xmlAttr *old_attr, void *user_data)
13961396
13971397/*!
13981398 * \internal
1399- * \brief Check all attributes in new XML for creation
1399+ * \brief Mark a new attribute dirty if ACLs allow creation, or remove otherwise
14001400 *
1401- * For each of a given XML element's attributes marked as newly created, accept
1402- * (and mark as dirty) or reject the creation according to ACLs.
1401+ * We set the \c pcmk__xf_created flag on all attributes in the new XML at an
1402+ * earlier stage of change calculation. Then we checked whether each attribute
1403+ * was present in the old XML, and we cleared the flag if so. If the flag is
1404+ * still set, then the attribute is truly new.
14031405 *
1404- * \param[in,out] new_xml XML to check
1406+ * Now we check whether ACLs allow the attribute's creation. If so, we "accept"
1407+ * it: we mark the attribute as dirty and modified, and we mark all of its
1408+ * parents as dirty. Otherwise, we reject it by removing the attribute (ignoring
1409+ * ACLs and change tracking for the removal).
1410+ *
1411+ * \param[in,out] attr XML attribute to mark dirty or remove
1412+ * \param[in] user_data Ignored
1413+ *
1414+ * \return \c true (to continue iterating)
1415+ *
1416+ * \note This is compatible with \c pcmk__xe_foreach_attr().
14051417 */
1406- static void
1407- mark_created_attrs ( xmlNode * new_xml )
1418+ static bool
1419+ check_new_attr_acls ( xmlAttr * attr , void * user_data )
14081420{
1409- for ( xmlAttr * attr = pcmk__xe_first_attr ( new_xml ); attr != NULL ;
1410- attr = attr -> next ) {
1411-
1412- const char * name = ( const char * ) attr -> name ;
1413- xml_node_private_t * nodepriv = attr -> _private ;
1421+ const char * name = ( const char * ) attr -> name ;
1422+ const char * value = pcmk__xml_attr_value ( attr );
1423+ const xml_node_private_t * nodepriv = attr -> _private ;
1424+ xmlNode * new_xml = attr -> parent ;
1425+ const char * new_xml_id = pcmk__s ( pcmk__xe_id ( new_xml ), "without ID" ) ;
14141426
1415- if (!pcmk__is_set (nodepriv -> flags , pcmk__xf_created )) {
1416- continue ;
1417- }
1418-
1419- pcmk__trace ("Created new attribute %s=%s in %s" , name ,
1420- pcmk__xml_attr_value (attr ), (const char * ) new_xml -> name );
1421-
1422- /* Check ACLs (we can't use the remove-then-create trick because it
1423- * would modify the attribute position).
1424- */
1425- if (pcmk__check_acl (new_xml , name , pcmk__xf_acl_write )) {
1426- pcmk__mark_xml_attr_dirty (attr );
1427+ if (!pcmk__is_set (nodepriv -> flags , pcmk__xf_created )) {
1428+ return true;
1429+ }
14271430
1428- } else {
1429- // Creation was not allowed, so remove the attribute
1430- pcmk__xa_remove (attr , true);
1431- }
1431+ /* Check ACLs (we can't use the remove-then-create trick because it
1432+ * would modify the attribute position).
1433+ */
1434+ if (!pcmk__check_acl (new_xml , name , pcmk__xf_acl_write )) {
1435+ pcmk__trace ("ACLs prevent creation of attribute %s=%s in %s %s" , name ,
1436+ value , (const char * ) new_xml -> name , new_xml_id );
1437+ pcmk__xa_remove (attr , true);
1438+ return true;
14321439 }
1440+
1441+ pcmk__trace ("Created new attribute %s=%s in %s %s" , name , value ,
1442+ (const char * ) new_xml -> name , new_xml_id );
1443+ pcmk__mark_xml_attr_dirty (attr );
1444+ return true;
14331445}
14341446
14351447/*!
@@ -1451,7 +1463,7 @@ xml_diff_attrs(xmlNode *old_xml, xmlNode *new_xml)
14511463 }
14521464
14531465 pcmk__xe_foreach_attr (old_xml , mark_attr_diff , new_xml );
1454- mark_created_attrs (new_xml );
1466+ pcmk__xe_foreach_attr (new_xml , check_new_attr_acls , NULL );
14551467}
14561468
14571469/*!
0 commit comments