Fix infinite loop in role hierarchy resolving

Issue: gh-7035
This commit is contained in:
Karel Maxa 2019-07-11 15:43:26 +02:00
parent 2d36062846
commit d3eaef66fc
2 changed files with 12 additions and 20 deletions

View File

@ -215,33 +215,19 @@ public class RoleHierarchyImpl implements RoleHierarchy {
// iterate over all higher roles from rolesReachableInOneStepMap // iterate over all higher roles from rolesReachableInOneStepMap
for (GrantedAuthority role : this.rolesReachableInOneStepMap.keySet()) { for (GrantedAuthority role : this.rolesReachableInOneStepMap.keySet()) {
Set<GrantedAuthority> rolesToVisitSet = new HashSet<>(); Set<GrantedAuthority> rolesToVisitSet = new HashSet<>(this.rolesReachableInOneStepMap.get(role));
if (this.rolesReachableInOneStepMap.containsKey(role)) {
rolesToVisitSet.addAll(this.rolesReachableInOneStepMap.get(role));
}
Set<GrantedAuthority> visitedRolesSet = new HashSet<>(); Set<GrantedAuthority> visitedRolesSet = new HashSet<>();
while (!rolesToVisitSet.isEmpty()) { while (!rolesToVisitSet.isEmpty()) {
// take a role from the rolesToVisit set // take a role from the rolesToVisit set
GrantedAuthority aRole = rolesToVisitSet.iterator().next(); GrantedAuthority aRole = rolesToVisitSet.iterator().next();
rolesToVisitSet.remove(aRole); rolesToVisitSet.remove(aRole);
visitedRolesSet.add(aRole); if (!visitedRolesSet.add(aRole) || !this.rolesReachableInOneStepMap.containsKey(aRole)) {
if (this.rolesReachableInOneStepMap.containsKey(aRole)) { continue; // Already visited role or role with missing hierarchy
Set<GrantedAuthority> newReachableRoles = this.rolesReachableInOneStepMap } else if (role.equals(aRole)) {
.get(aRole);
// definition of a cycle: you can reach the role you are starting from
if (rolesToVisitSet.contains(role)
|| visitedRolesSet.contains(role)) {
throw new CycleInRoleHierarchyException(); throw new CycleInRoleHierarchyException();
} }
else { rolesToVisitSet.addAll(this.rolesReachableInOneStepMap.get(aRole));
// no cycle
rolesToVisitSet.addAll(newReachableRoles);
}
}
} }
this.rolesReachableInOneOrMoreStepsMap.put(role, visitedRolesSet); this.rolesReachableInOneOrMoreStepsMap.put(role, visitedRolesSet);

View File

@ -168,6 +168,12 @@ public class RoleHierarchyImplTests {
} }
catch (CycleInRoleHierarchyException e) { catch (CycleInRoleHierarchyException e) {
} }
try {
roleHierarchyImpl.setHierarchy("ROLE_C > ROLE_B\nROLE_B > ROLE_A\nROLE_A > ROLE_B");
fail("Cycle in role hierarchy was not detected!");
} catch (CycleInRoleHierarchyException e) {
}
} }
@Test @Test