@@ -1345,40 +1345,52 @@ mark_attr_diff(xmlAttr *old_attr, void *user_data)
13451345
13461346/*!
13471347 * \internal
1348- * \brief Check all attributes in new XML for creation
1348+ * \brief Mark a new attribute dirty if ACLs allow creation, or remove otherwise
13491349 *
1350- * For each of a given XML element's attributes marked as newly created, accept
1351- * (and mark as dirty) or reject the creation according to ACLs.
1350+ * We set the \c pcmk__xf_created flag on all attributes in the new XML at an
1351+ * earlier stage of change calculation. Then we checked whether each attribute
1352+ * was present in the old XML, and we cleared the flag if so. If the flag is
1353+ * still set, then the attribute is truly new.
13521354 *
1353- * \param[in,out] new_xml XML to check
1355+ * Now we check whether ACLs allow the attribute's creation. If so, we "accept"
1356+ * it: we mark the attribute as dirty and modified, and we mark all of its
1357+ * parents as dirty. Otherwise, we reject it by removing the attribute (ignoring
1358+ * ACLs and change tracking for the removal).
1359+ *
1360+ * \param[in,out] attr XML attribute to mark dirty or remove
1361+ * \param[in] user_data Ignored
1362+ *
1363+ * \return \c true (to continue iterating)
1364+ *
1365+ * \note This is compatible with \c pcmk__xe_foreach_attr().
13541366 */
1355- static void
1356- mark_created_attrs ( xmlNode * new_xml )
1367+ static bool
1368+ check_new_attr_acls ( xmlAttr * attr , void * user_data )
13571369{
1358- for ( xmlAttr * attr = pcmk__xe_first_attr ( new_xml ); attr != NULL ;
1359- attr = attr -> next ) {
1360-
1361- const char * name = ( const char * ) attr -> name ;
1362- xml_node_private_t * nodepriv = attr -> _private ;
1370+ const char * name = ( const char * ) attr -> name ;
1371+ const char * value = pcmk__xml_attr_value ( attr );
1372+ const xml_node_private_t * nodepriv = attr -> _private ;
1373+ xmlNode * new_xml = attr -> parent ;
1374+ const char * new_xml_id = pcmk__s ( pcmk__xe_id ( new_xml ), "without ID" ) ;
13631375
1364- if (!pcmk__is_set (nodepriv -> flags , pcmk__xf_created )) {
1365- continue ;
1366- }
1367-
1368- pcmk__trace ("Created new attribute %s=%s in %s" , name ,
1369- pcmk__xml_attr_value (attr ), (const char * ) new_xml -> name );
1370-
1371- /* Check ACLs (we can't use the remove-then-create trick because it
1372- * would modify the attribute position).
1373- */
1374- if (pcmk__check_acl (new_xml , name , pcmk__xf_acl_write )) {
1375- pcmk__mark_xml_attr_dirty (attr );
1376+ if (!pcmk__is_set (nodepriv -> flags , pcmk__xf_created )) {
1377+ return true;
1378+ }
13761379
1377- } else {
1378- // Creation was not allowed, so remove the attribute
1379- pcmk__xa_remove (attr , true);
1380- }
1380+ /* Check ACLs (we can't use the remove-then-create trick because it
1381+ * would modify the attribute position).
1382+ */
1383+ if (!pcmk__check_acl (new_xml , name , pcmk__xf_acl_write )) {
1384+ pcmk__trace ("ACLs prevent creation of attribute %s=%s in %s %s" , name ,
1385+ value , (const char * ) new_xml -> name , new_xml_id );
1386+ pcmk__xa_remove (attr , true);
1387+ return true;
13811388 }
1389+
1390+ pcmk__trace ("Created new attribute %s=%s in %s %s" , name , value ,
1391+ (const char * ) new_xml -> name , new_xml_id );
1392+ pcmk__mark_xml_attr_dirty (attr );
1393+ return true;
13821394}
13831395
13841396/*!
@@ -1400,7 +1412,7 @@ xml_diff_attrs(xmlNode *old_xml, xmlNode *new_xml)
14001412 }
14011413
14021414 pcmk__xe_foreach_attr (old_xml , mark_attr_diff , new_xml );
1403- mark_created_attrs (new_xml );
1415+ pcmk__xe_foreach_attr (new_xml , check_new_attr_acls , NULL );
14041416}
14051417
14061418/*!
0 commit comments