From c73cdcfffad22502da2a54cd1d3970267d145750 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 :

---
 opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java |   98 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 97 insertions(+), 1 deletions(-)

diff --git a/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java b/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
index 290db5f..c719c6e 100644
--- a/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
+++ b/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;
+  }
 }
 

--
Gitblit v1.10.0