diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java index 52f7b09ac3..0ba662c9a4 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java @@ -13,6 +13,7 @@ * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC */ package org.opends.server.authorization.dseecompat; @@ -146,11 +147,17 @@ private BindRule(BindRule left, BindRule right, EnumBooleanTypes booleanType) { * @throws AciException If the string is an invalid bind rule. */ public static BindRule decode (String input) throws AciException { - if (input == null || input.length() == 0) + if (input == null) { return null; } String bindruleStr = input.trim(); + if (bindruleStr.isEmpty()) + { + // A blank bind rule (e.g. "( )") must be rejected as a + // syntax error rather than throwing StringIndexOutOfBoundsException. + return null; + } char firstChar = bindruleStr.charAt(0); char[] bindruleArray = bindruleStr.toCharArray(); diff --git a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciBodyTest.java b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciBodyTest.java index b006df42a4..ed3f15a448 100644 --- a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciBodyTest.java +++ b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciBodyTest.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2013-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC */ package org.opends.server.authorization.dseecompat; @@ -61,4 +62,15 @@ public void decodeValidAci(String aci) throws Exception assertThat(aciBody.toString()).isEqualTo(aci); assertThat(aciBody.getPermBindRulePairs()).hasSize(1); } + + /** + * A blank bind rule (only whitespace between the parentheses) must be + * rejected with an {@link AciException} rather than crashing with an + * unchecked {@code StringIndexOutOfBoundsException}. See issue #712. + */ + @Test(expectedExceptions = AciException.class) + public void decodeBlankBindRuleThrowsAciException() throws Exception + { + AciBody.decode("(version 3.0; acl \"C\"; allow (search)( ) (userdn=\"ldap:///self\"); )"); + } }