浏览代码

Prevent StackOverflowError for AccessControlEntryImpl.hashCode

Getting StackOverflowError when invoke AclImpl.hashCode because of
cross-references between AclImpl and AccessControlEntryImpl

Remove from AccessControlEntryImpl.hashCode method invocation of
acl.hashCode

fixes gh-5401
Maksim Vinogradov 6 年之前
父节点
当前提交
8bb4e72aff

+ 3 - 4
acl/src/main/java/org/springframework/security/acls/domain/AccessControlEntryImpl.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ * Copyright 2002-2016 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -131,10 +131,9 @@ public class AccessControlEntryImpl implements AccessControlEntry,
 
 	@Override
 	public int hashCode() {
-		int result = this.acl.hashCode();
-		result = 31 * result + this.permission.hashCode();
+		int result = this.permission.hashCode();
 		result = 31 * result + (this.id != null ? this.id.hashCode() : 0);
-		result = 31 * result + this.sid.hashCode();
+		result = 31 * result + (this.sid.hashCode());
 		result = 31 * result + (this.auditFailure ? 1 : 0);
 		result = 31 * result + (this.auditSuccess ? 1 : 0);
 		result = 31 * result + (this.granting ? 1 : 0);

+ 20 - 1
acl/src/test/java/org/springframework/security/acls/domain/AclImplTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -560,6 +560,25 @@ public class AclImplTests {
 		childAcl.setParent(changeParentAcl);
 	}
 
+	@Test
+	public void hashCodeWithoutStackOverFlow() throws Exception {
+		//given
+		Sid sid = new PrincipalSid("pSid");
+		ObjectIdentity oid = new ObjectIdentityImpl("type", 1);
+		AclAuthorizationStrategy authStrategy = new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("role"));
+		PermissionGrantingStrategy grantingStrategy = new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
+
+		AclImpl acl = new AclImpl(oid, 1L, authStrategy, grantingStrategy, null, null, false, sid);
+		AccessControlEntryImpl ace = new AccessControlEntryImpl(1L, acl, sid, BasePermission.READ, true, true, true);
+
+		Field fieldAces = FieldUtils.getField(AclImpl.class, "aces");
+		fieldAces.setAccessible(true);
+		List<AccessControlEntryImpl> aces = (List<AccessControlEntryImpl>) fieldAces.get(acl);
+		aces.add(ace);
+		//when - then none StackOverFlowError been raised
+		ace.hashCode();
+	}
+
 	// ~ Inner Classes
 	// ==================================================================================================