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
for (GrantedAuthority role : this.rolesReachableInOneStepMap.keySet()) {
Set<GrantedAuthority> rolesToVisitSet = new HashSet<>();
if (this.rolesReachableInOneStepMap.containsKey(role)) {
rolesToVisitSet.addAll(this.rolesReachableInOneStepMap.get(role));
}
Set<GrantedAuthority> rolesToVisitSet = new HashSet<>(this.rolesReachableInOneStepMap.get(role));
Set<GrantedAuthority> visitedRolesSet = new HashSet<>();
while (!rolesToVisitSet.isEmpty()) {
// take a role from the rolesToVisit set
GrantedAuthority aRole = rolesToVisitSet.iterator().next();
rolesToVisitSet.remove(aRole);
visitedRolesSet.add(aRole);
if (this.rolesReachableInOneStepMap.containsKey(aRole)) {
Set<GrantedAuthority> newReachableRoles = this.rolesReachableInOneStepMap
.get(aRole);
// definition of a cycle: you can reach the role you are starting from
if (rolesToVisitSet.contains(role)
|| visitedRolesSet.contains(role)) {
if (!visitedRolesSet.add(aRole) || !this.rolesReachableInOneStepMap.containsKey(aRole)) {
continue; // Already visited role or role with missing hierarchy
} else if (role.equals(aRole)) {
throw new CycleInRoleHierarchyException();
}
else {
// no cycle
rolesToVisitSet.addAll(newReachableRoles);
}
}
rolesToVisitSet.addAll(this.rolesReachableInOneStepMap.get(aRole));
}
this.rolesReachableInOneOrMoreStepsMap.put(role, visitedRolesSet);

View File

@ -168,6 +168,12 @@ public class RoleHierarchyImplTests {
}
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