From ec8dd4540b7be98f80e073c1df7bbc536241571a Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Tue, 05 Dec 2006 04:16:14 +0000
Subject: [PATCH] org.opends.server.schema.LDAPSyntaxDescription.java does not accept extensions as specified by RFC4512 :
---
opendj-sdk/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java | 98 ++++++++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java | 26 ++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java | 73 +++++++++++++++---
3 files changed, 183 insertions(+), 14 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java
index 4d55bd4..47e7233 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java
@@ -2945,7 +2945,24 @@
public static final int MSGID_ATTR_SYNTAX_AUTHPW_INVALID_TRAILING_CHAR =
CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_ERROR | 263;
+ /**
+ * The message ID for the message that will be used if an attribute syntax
+ * extension value cannot be parsed because an invalid character was found.
+ * This takes a two arguments, which are the provided value, and the position
+ * of the invalid character.
+ */
+ public static final int
+ MSGID_ATTR_SYNTAX_ATTRSYNTAX_EXTENSION_INVALID_CHARACTER =
+ CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 264;
+ /**
+ * The message ID for the message that will be used if an attribute syntax
+ * extension value cannot be parsed. This takes one argument, a string
+ * representation of the exception that was caught.
+ */
+ public static final int
+ MSGID_ATTR_SYNTAX_ATTRSYNTAX_INVALID_EXTENSION =
+ CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 265;
/**
* Associates a set of generic messages with the message IDs defined in this
@@ -4178,6 +4195,15 @@
registerMessage(MSGID_ATTR_SYNTAX_RELATIVE_SUBTREE_SPECIFICATION_INVALID,
"The provided value \"%s\" could not be parsed as a" +
" valid relative subtree specification.");
+
+ registerMessage(MSGID_ATTR_SYNTAX_ATTRSYNTAX_EXTENSION_INVALID_CHARACTER,
+ "The provided value \"%s\" could not be parsed as an " +
+ "attribute syntax extension because an invalid character"+
+ "was found at position %d.");
+
+ registerMessage(MSGID_ATTR_SYNTAX_ATTRSYNTAX_INVALID_EXTENSION,
+ "The attribute syntax could not be parsed because of an"+
+ "invalid extension."+ "%s.");
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
index 290db5f..c719c6e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
@@ -469,7 +469,19 @@
stackTraceToSingleLineString(e)));
return false;
}
-
+ //Check if we have a RFC 4512 style extension.
+ if ((c = valueStr.charAt(pos)) != ')')
+ {
+ try {
+ pos=parseExtension(valueStr, pos);
+ } catch (Exception e) {
+ assert debugException(CLASS_NAME, "valueIsAcceptable", e);
+ int msgID = MSGID_ATTR_SYNTAX_ATTRSYNTAX_INVALID_EXTENSION;
+ invalidReason.append(getMessage(msgID,
+ stackTraceToSingleLineString(e)));
+ return false;
+ }
+ }
// The next character must be the closing parenthesis and there should not
// be anything after it (except maybe some spaces).
@@ -642,5 +654,89 @@
// Return the position of the first non-space character after the token.
return startPos;
}
+
+ /** Parses a RFC 4512 extensions (see 4.1.5 and 4.1 of the RFC) definition.
+ *
+ * From 4.1.5 of the spec:
+ *
+ * LDAP syntax definitions are written according to the ABNF:
+ *
+ * SyntaxDescription = LPAREN WSP
+ * numericoid ; object identifier
+ * [ SP "DESC" SP qdstring ] ; description
+ * extensions WSP RPAREN ; extensions
+ *
+ * @param valueStr The user-provided representation of the extensions
+ * definition.
+ *
+ * @param startPos The position in the provided string at which to start
+ * reading the quoted string.
+ *
+ * @return The position of the first character that is not part of the quoted
+ * string or one of the trailing spaces after it.
+ *
+ * @throws DirectoryException If the extensions definition could not be
+ * parsed.
+ */
+private static int parseExtension(String valueStr, int startPos)
+ throws DirectoryException {
+
+ int pos=startPos, len=valueStr.length();
+ char c;
+ while(true)
+ {
+ StringBuilder tokenNameBuffer = new StringBuilder();
+ pos = readTokenName(valueStr, tokenNameBuffer, pos);
+ String tokenName = tokenNameBuffer.toString();
+ if((tokenName.length() <= 2) || (!tokenName.startsWith("X-")))
+ {
+ int msgID =
+ MSGID_ATTR_SYNTAX_ATTRSYNTAX_EXTENSION_INVALID_CHARACTER;
+ String message = getMessage(msgID, valueStr);
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message, msgID);
+ }
+ String xstring = tokenName.substring(2);
+ //Only allow a-z,A-Z,-,_ characters after X-
+ if(xstring.split("^[A-Za-z_-]+").length > 0)
+ {
+ int msgID =
+ MSGID_ATTR_SYNTAX_ATTRSYNTAX_EXTENSION_INVALID_CHARACTER;
+ String message = getMessage(msgID, valueStr);
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message, msgID);
+ }
+ if((c=valueStr.charAt(pos)) == '\'')
+ {
+ StringBuilder qdString = new StringBuilder();
+ pos = readQuotedString(valueStr, qdString, pos);
+
+ } else if(c == '(')
+ {
+ pos++;
+ StringBuilder qdString = new StringBuilder();
+ while ((c=valueStr.charAt(pos)) != ')')
+ pos = readQuotedString(valueStr, qdString, pos);
+ pos++;
+ } else
+ {
+ int msgID =
+ MSGID_ATTR_SYNTAX_ATTRSYNTAX_EXTENSION_INVALID_CHARACTER;
+ String message = getMessage(msgID, valueStr);
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message, msgID);
+ }
+ if (pos >= len)
+ {
+ int msgID = MSGID_ATTR_SYNTAX_ATTRSYNTAX_TRUNCATED_VALUE;
+ String message = getMessage(msgID, valueStr);
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message, msgID);
+ }
+ if(valueStr.charAt(pos) == ')')
+ break;
+ }
+ return pos;
+ }
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java
index 418ccf3..2024535 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java
@@ -51,19 +51,66 @@
@DataProvider(name="acceptableValues")
public Object[][] createAcceptableValues()
{
- return new Object [][] {
- // disabled because test is failing :
- // {
- // "( 2.5.4.3 DESC 'full syntax description' "
- // + "( this is an extension ) )", true},
- {"( 2.5.4.3 DESC 'full syntax description' )", true},
- {" ( 2.5.4.3 DESC ' syntax description' )", true},
- {"( 2.5.4.3 DESC syntax description )", false},
- {"($%^*&!@ DESC 'syntax description' )", false},
- {"(temp-oid DESC 'syntax description' )", true},
- {"2.5.4.3 DESC 'syntax description' )", false},
- {"(2.5.4.3 DESC 'syntax description' ", false},
- };
+ return new Object [][] {
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-9EN ('this' 'is' 'a' 'test'))",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "(X-name 'this",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "(X-name 'this'",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "Y-name 'this')",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name 'this' 'is')",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name )",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X- ('this' 'is' 'a' 'test'))",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this')",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this'",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this'))))",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name ('this' 'is' 'a' 'test') X-name-a X-name-b ('this'))))",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name ('this' 'is' 'a' 'test') X-name-a 'X-name-b' ('this'))))",
+ false},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this'))",
+ true},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-a-_eN_- ('this' 'is' 'a' 'test'))",
+ true},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name ('this'))",
+ true},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name 'this')",
+ true},
+ {"( 2.5.4.3 DESC 'full syntax description' " +
+ "X-name 'this' X-name-a 'test')",
+ true},
+ {"( 2.5.4.3 DESC 'full syntax description' )", true},
+ {" ( 2.5.4.3 DESC ' syntax description' )", true},
+ {"( 2.5.4.3 DESC syntax description )", false},
+ {"($%^*&!@ DESC 'syntax description' )", false},
+ {"(temp-oid DESC 'syntax description' )", true},
+ {"2.5.4.3 DESC 'syntax description' )", false},
+ {"(2.5.4.3 DESC 'syntax description' ", false},
+ };
}
}
--
Gitblit v1.10.0