@@ -1390,40 +1390,52 @@ mark_attr_diff(xmlAttr *old_attr, void *user_data)
13901390
13911391/*!
13921392 * \internal
1393- * \brief Check all attributes in new XML for creation
1393+ * \brief Mark a new attribute dirty if ACLs allow creation, or remove otherwise
13941394 *
1395- * For each of a given XML element's attributes marked as newly created, accept
1396- * (and mark as dirty) or reject the creation according to ACLs.
1395+ * We set the \c pcmk__xf_created flag on all attributes in the new XML at an
1396+ * earlier stage of change calculation. Then we checked whether each attribute
1397+ * was present in the old XML, and we cleared the flag if so. If the flag is
1398+ * still set, then the attribute is truly new.
13971399 *
1398- * \param[in,out] new_xml XML to check
1400+ * Now we check whether ACLs allow the attribute's creation. If so, we "accept"
1401+ * it: we mark the attribute as dirty and modified, and we mark all of its
1402+ * parents as dirty. Otherwise, we reject it by removing the attribute (ignoring
1403+ * ACLs and change tracking for the removal).
1404+ *
1405+ * \param[in,out] attr XML attribute to mark dirty or remove
1406+ * \param[in] user_data Ignored
1407+ *
1408+ * \return \c true (to continue iterating)
1409+ *
1410+ * \note This is compatible with \c pcmk__xe_foreach_attr().
13991411 */
1400- static void
1401- mark_created_attrs ( xmlNode * new_xml )
1412+ static bool
1413+ check_new_attr_acls ( xmlAttr * attr , void * user_data )
14021414{
1403- for ( xmlAttr * attr = pcmk__xe_first_attr ( new_xml ); attr != NULL ;
1404- attr = attr -> next ) {
1405-
1406- const char * name = ( const char * ) attr -> name ;
1407- xml_node_private_t * nodepriv = attr -> _private ;
1415+ const char * name = ( const char * ) attr -> name ;
1416+ const char * value = pcmk__xml_attr_value ( attr );
1417+ const xml_node_private_t * nodepriv = attr -> _private ;
1418+ xmlNode * new_xml = attr -> parent ;
1419+ const char * new_xml_id = pcmk__s ( pcmk__xe_id ( new_xml ), "without ID" ) ;
14081420
1409- if (!pcmk__is_set (nodepriv -> flags , pcmk__xf_created )) {
1410- continue ;
1411- }
1412-
1413- pcmk__trace ("Created new attribute %s=%s in %s" , name ,
1414- pcmk__xml_attr_value (attr ), (const char * ) new_xml -> name );
1415-
1416- /* Check ACLs (we can't use the remove-then-create trick because it
1417- * would modify the attribute position).
1418- */
1419- if (pcmk__check_acl (new_xml , name , pcmk__xf_acl_write )) {
1420- pcmk__mark_xml_attr_dirty (attr );
1421+ if (!pcmk__is_set (nodepriv -> flags , pcmk__xf_created )) {
1422+ return true;
1423+ }
14211424
1422- } else {
1423- // Creation was not allowed, so remove the attribute
1424- pcmk__xa_remove (attr , true);
1425- }
1425+ /* Check ACLs (we can't use the remove-then-create trick because it
1426+ * would modify the attribute position).
1427+ */
1428+ if (!pcmk__check_acl (new_xml , name , pcmk__xf_acl_write )) {
1429+ pcmk__trace ("ACLs prevent creation of attribute %s=%s in %s %s" , name ,
1430+ value , (const char * ) new_xml -> name , new_xml_id );
1431+ pcmk__xa_remove (attr , true);
1432+ return true;
14261433 }
1434+
1435+ pcmk__trace ("Created new attribute %s=%s in %s %s" , name , value ,
1436+ (const char * ) new_xml -> name , new_xml_id );
1437+ pcmk__mark_xml_attr_dirty (attr );
1438+ return true;
14271439}
14281440
14291441/*!
@@ -1445,7 +1457,7 @@ xml_diff_attrs(xmlNode *old_xml, xmlNode *new_xml)
14451457 }
14461458
14471459 pcmk__xe_foreach_attr (old_xml , mark_attr_diff , new_xml );
1448- mark_created_attrs (new_xml );
1460+ pcmk__xe_foreach_attr (new_xml , check_new_attr_acls , NULL );
14491461}
14501462
14511463/*!
0 commit comments