From 14c8bca1f415a6a6a6cd27cec775c2d1e52427aa Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Fri, 01 May 2009 01:14:55 +0000
Subject: [PATCH] Second fix for issue 3949: All ASN.1 parsing code now ignores trailing unrecognized SEQUENCE components.

---
 opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java                        |   39 -
 opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteSequenceReader.java                             |   12 
 opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1InputStreamReader.java                              |   22 +
 opendj-sdk/opends/src/server/org/opends/server/controls/AccountUsableResponseControl.java                             |   51 +-
 opendj-sdk/opends/src/server/org/opends/server/controls/PasswordPolicyResponseControl.java                            |   64 +--
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ReaderTestCase.java         |    9 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestBindResponseProtocolOp.java |   41 +
 opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPReader.java                                         |  372 ++++++++++-----------
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestSearchProtocolOp.java       |   30 +
 opendj-sdk/opends/src/server/org/opends/server/controls/EntryChangeNotificationControl.java                           |   41 +-
 opendj-sdk/opends/src/server/org/opends/server/types/RawFilter.java                                                   |   88 ++---
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java     |    8 
 opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java                           |   27 -
 opendj-sdk/opends/src/server/org/opends/server/controls/ServerSideSortRequestControl.java                             |   46 +-
 opendj-sdk/opends/src/server/org/opends/server/controls/MatchedValuesFilter.java                                      |  127 +-----
 15 files changed, 444 insertions(+), 533 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/controls/AccountUsableResponseControl.java b/opendj-sdk/opends/src/server/org/opends/server/controls/AccountUsableResponseControl.java
index 49367c5..a86577c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/controls/AccountUsableResponseControl.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/controls/AccountUsableResponseControl.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.controls;
 import org.opends.messages.Message;
@@ -103,32 +103,31 @@
             int     secondsBeforeUnlock = 0;
 
             reader.readStartSequence();
-            while(reader.hasNextElement())
+            if(reader.hasNextElement() &&
+                reader.peekType() == TYPE_INACTIVE)
             {
-              switch (reader.peekType())
-              {
-                case TYPE_INACTIVE:
-                  isInactive = reader.readBoolean();
-                  break;
-                case TYPE_RESET:
-                  isReset = reader.readBoolean();
-                  break;
-                case TYPE_EXPIRED:
-                  isExpired = reader.readBoolean();
-                  break;
-                case TYPE_REMAINING_GRACE_LOGINS:
-                  remainingGraceLogins = (int)reader.readInteger();
-                  break;
-                case TYPE_SECONDS_BEFORE_UNLOCK:
-                  isLocked = true;
-                  secondsBeforeUnlock = (int)reader.readInteger();
-                  break;
-                default:
-                  Message message = ERR_ACCTUSABLERES_UNKNOWN_UNAVAILABLE_TYPE.
-                      get(byteToHex(reader.peekType()));
-                  throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
-                      message);
-              }
+              isInactive = reader.readBoolean();
+            }
+            if(reader.hasNextElement() &&
+                reader.peekType() == TYPE_RESET)
+            {
+              isReset = reader.readBoolean();
+            }
+            if(reader.hasNextElement() &&
+                reader.peekType() == TYPE_EXPIRED)
+            {
+              isExpired = reader.readBoolean();
+            }
+            if(reader.hasNextElement() &&
+                reader.peekType() == TYPE_REMAINING_GRACE_LOGINS)
+            {
+              remainingGraceLogins = (int)reader.readInteger();
+            }
+            if(reader.hasNextElement() &&
+                reader.peekType() == TYPE_SECONDS_BEFORE_UNLOCK)
+            {
+              isLocked = true;
+              secondsBeforeUnlock = (int)reader.readInteger();
             }
             reader.readEndSequence();
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/controls/EntryChangeNotificationControl.java b/opendj-sdk/opends/src/server/org/opends/server/controls/EntryChangeNotificationControl.java
index ef01791..f9f4607 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/controls/EntryChangeNotificationControl.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/controls/EntryChangeNotificationControl.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.controls;
 import org.opends.messages.Message;
@@ -33,6 +33,8 @@
 import org.opends.server.protocols.asn1.*;
 import static org.opends.server.protocols.asn1.ASN1Constants.
     UNIVERSAL_OCTET_STRING_TYPE;
+import static org.opends.server.protocols.asn1.ASN1Constants.
+    UNIVERSAL_INTEGER_TYPE;
 import org.opends.server.types.*;
 
 import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -81,28 +83,23 @@
         int changeTypeValue = (int)reader.readInteger();
         changeType = PersistentSearchChangeType.valueOf(changeTypeValue);
 
-        while(reader.hasNextElement()) {
-          switch(reader.peekType()) {
-            case ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE :
-              if (changeType != PersistentSearchChangeType.MODIFY_DN)
-              {
-                Message message =
-                    ERR_ECN_ILLEGAL_PREVIOUS_DN.get(String.valueOf(changeType));
-                throw new DirectoryException(
-                    ResultCode.PROTOCOL_ERROR, message);
-              }
-
-              previousDN = DN.decode(reader.readOctetStringAsString());
-              break;
-            case ASN1Constants.UNIVERSAL_INTEGER_TYPE :
-              changeNumber = reader.readInteger();
-              break;
-            default :
-              Message message =
-                  ERR_ECN_INVALID_ELEMENT_TYPE.get(
-                      byteToHex(reader.peekType()));
-              throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
+        if(reader.hasNextElement() &&
+            reader.peekType() == UNIVERSAL_OCTET_STRING_TYPE)
+        {
+          if (changeType != PersistentSearchChangeType.MODIFY_DN)
+          {
+            Message message =
+                ERR_ECN_ILLEGAL_PREVIOUS_DN.get(String.valueOf(changeType));
+            throw new DirectoryException(
+                ResultCode.PROTOCOL_ERROR, message);
           }
+
+          previousDN = DN.decode(reader.readOctetStringAsString());
+        }
+        if(reader.hasNextElement() &&
+            reader.peekType() == UNIVERSAL_INTEGER_TYPE)
+        {
+          changeNumber = reader.readInteger();
         }
       }
       catch (DirectoryException de)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/controls/MatchedValuesFilter.java b/opendj-sdk/opends/src/server/org/opends/server/controls/MatchedValuesFilter.java
index bde20fe..2895360 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/controls/MatchedValuesFilter.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/controls/MatchedValuesFilter.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.controls;
 import org.opends.messages.Message;
@@ -786,50 +786,25 @@
           ByteString subInitial        = null;
           ArrayList<ByteString> subAny = null;
           ByteString subFinal          = null;
-          while(reader.hasNextElement())
+
+          if(reader.hasNextElement() &&
+              reader.peekType() == TYPE_SUBINITIAL)
           {
-            switch(reader.peekType())
+            subInitial = reader.readOctetString();
+          }
+          while(reader.hasNextElement() &&
+              reader.peekType() == TYPE_SUBANY)
+          {
+            if(subAny == null)
             {
-             case TYPE_SUBINITIAL:
-                if (subInitial == null)
-                {
-                  subInitial = reader.readOctetString();
-                }
-                else
-                {
-                  Message message = ERR_MVFILTER_MULTIPLE_SUBINITIALS.get();
-                  throw new LDAPException(
-                          LDAPResultCode.PROTOCOL_ERROR, message);
-                }
-                break;
-
-              case TYPE_SUBANY:
-                if (subAny == null)
-                {
-                  subAny = new ArrayList<ByteString>();
-                }
-
-                subAny.add(reader.readOctetString());
-                break;
-
-              case TYPE_SUBFINAL:
-                if (subFinal == null)
-                {
-                  subFinal = reader.readOctetString();
-                }
-                else
-                {
-                  Message message = ERR_MVFILTER_MULTIPLE_SUBFINALS.get();
-                  throw new LDAPException(
-                          LDAPResultCode.PROTOCOL_ERROR, message);
-                }
-                break;
-
-              default:
-                Message message = ERR_MVFILTER_INVALID_SUBSTRING_ELEMENT_TYPE.
-                    get(byteToHex(reader.peekType()));
-                throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
+              subAny = new ArrayList<ByteString>();
             }
+            subAny.add(reader.readOctetString());
+          }
+          if(reader.hasNextElement() &&
+              reader.peekType() == TYPE_SUBFINAL)
+          {
+            subFinal = reader.readOctetString();
           }
           reader.readEndSequence();
 
@@ -888,70 +863,26 @@
         {
           reader.readStartSequence();
 
-          String          rawAttributeType  = null;
-          String          matchingRuleID    = null;
-          ByteString rawAssertionValue = null;
-          while(reader.hasNextElement())
+          String     rawAttributeType  = null;
+          String     matchingRuleID    = null;
+          ByteString rawAssertionValue;
+
+          if(reader.peekType() == TYPE_MATCHING_RULE_ID)
           {
-            switch (reader.peekType())
-            {
-              case TYPE_MATCHING_RULE_ID:
-                if (matchingRuleID == null)
-                {
-                  matchingRuleID = reader.readOctetStringAsString();
-                }
-                else
-                {
-                  Message message =
-                      ERR_MVFILTER_MULTIPLE_MATCHING_RULE_IDS.get();
-                  throw new LDAPException(
-                          LDAPResultCode.PROTOCOL_ERROR, message);
-                }
-                break;
-
-              case TYPE_MATCHING_RULE_TYPE:
-                if (rawAttributeType == null)
-                {
-                  rawAttributeType = reader.readOctetStringAsString();
-                }
-                else
-                {
-                  Message message = ERR_MVFILTER_MULTIPLE_ATTRIBUTE_TYPES.get();
-                  throw new LDAPException(
-                          LDAPResultCode.PROTOCOL_ERROR, message);
-                }
-                break;
-
-              case TYPE_MATCHING_RULE_VALUE:
-                if (rawAssertionValue == null)
-                {
-                  rawAssertionValue = reader.readOctetString();
-                }
-                else
-                {
-                  Message message =
-                      ERR_MVFILTER_MULTIPLE_ASSERTION_VALUES.get();
-                  throw new LDAPException(
-                          LDAPResultCode.PROTOCOL_ERROR, message);
-                }
-                break;
-
-              default:
-                Message message = ERR_MVFILTER_INVALID_EXTENSIBLE_ELEMENT_TYPE.
-                    get(byteToHex(reader.peekType()));
-                throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
-            }
+            matchingRuleID = reader.readOctetStringAsString();
           }
+          if(matchingRuleID == null ||
+              reader.peekType() == TYPE_MATCHING_RULE_TYPE)
+          {
+             rawAttributeType = reader.readOctetStringAsString();
+          }
+          rawAssertionValue = reader.readOctetString();
           reader.readEndSequence();
 
           return new MatchedValuesFilter(type, rawAttributeType,
                                          rawAssertionValue, null, null, null,
                                          matchingRuleID);
         }
-        catch (LDAPException le)
-        {
-          throw le;
-        }
         catch (Exception e)
         {
           if (debugEnabled())
diff --git a/opendj-sdk/opends/src/server/org/opends/server/controls/PasswordPolicyResponseControl.java b/opendj-sdk/opends/src/server/org/opends/server/controls/PasswordPolicyResponseControl.java
index ae6cc4e..b45f309 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/controls/PasswordPolicyResponseControl.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/controls/PasswordPolicyResponseControl.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.controls;
 import org.opends.messages.Message;
@@ -81,43 +81,35 @@
 
         reader.readStartSequence();
 
-        while(reader.hasNextElement())
+        if(reader.hasNextElement() &&
+            reader.peekType() == TYPE_WARNING_ELEMENT)
         {
-          switch (reader.peekType())
+          // Its a CHOICE element. Read as sequence to retrieve
+          // nested element.
+          reader.readStartSequence();
+          warningType =
+              PasswordPolicyWarningType.valueOf(reader.peekType());
+          warningValue = (int)reader.readInteger();
+          if (warningType == null)
           {
-            case TYPE_WARNING_ELEMENT:
-              // Its a CHOICE element. Read as sequence to retrieve
-              // nested element.
-              reader.readStartSequence();
-              warningType =
-                  PasswordPolicyWarningType.valueOf(reader.peekType());
-              warningValue = (int)reader.readInteger();
-              if (warningType == null)
-              {
-                Message message = ERR_PWPOLICYRES_INVALID_WARNING_TYPE.get(
-                    byteToHex(reader.peekType()));
-                throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
-                    message);
-              }
-              reader.readEndSequence();
-              break;
-
-            case TYPE_ERROR_ELEMENT:
-              int errorValue = (int)reader.readInteger();
-              errorType = PasswordPolicyErrorType.valueOf(errorValue);
-              if (errorType == null)
-              {
-                Message message =
-                    ERR_PWPOLICYRES_INVALID_ERROR_TYPE.get(errorValue);
-                throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
-                    message);
-              }
-              break;
-
-            default:
-              Message message = ERR_PWPOLICYRES_INVALID_ELEMENT_TYPE.get(
-                  byteToHex(reader.peekType()));
-              throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
+            Message message = ERR_PWPOLICYRES_INVALID_WARNING_TYPE.get(
+                byteToHex(reader.peekType()));
+            throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+                message);
+          }
+          reader.readEndSequence();
+        }
+        if(reader.hasNextElement() &&
+            reader.peekType() == TYPE_ERROR_ELEMENT)
+        {
+          int errorValue = (int)reader.readInteger();
+          errorType = PasswordPolicyErrorType.valueOf(errorValue);
+          if (errorType == null)
+          {
+            Message message =
+                ERR_PWPOLICYRES_INVALID_ERROR_TYPE.get(errorValue);
+            throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+                message);
           }
         }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/controls/ServerSideSortRequestControl.java b/opendj-sdk/opends/src/server/org/opends/server/controls/ServerSideSortRequestControl.java
index a9c1361..b44f866 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/controls/ServerSideSortRequestControl.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/controls/ServerSideSortRequestControl.java
@@ -124,37 +124,28 @@
 
           OrderingMatchingRule orderingRule = null;
           boolean ascending = true;
-
-          while(reader.hasNextElement())
+          if(reader.hasNextElement() &&
+              reader.peekType() == TYPE_ORDERING_RULE_ID)
           {
-            switch (reader.peekType())
+            String orderingRuleID =
+                toLowerCase(reader.readOctetStringAsString());
+            orderingRule =
+                DirectoryServer.getOrderingMatchingRule(orderingRuleID);
+            if (orderingRule == null)
             {
-              case TYPE_ORDERING_RULE_ID:
-                String orderingRuleID =
-                               toLowerCase(reader.readOctetStringAsString());
-                orderingRule =
-                    DirectoryServer.getOrderingMatchingRule(orderingRuleID);
-                if (orderingRule == null)
-                {
-                  Message message =
-                      INFO_SORTREQ_CONTROL_UNDEFINED_ORDERING_RULE.
-                          get(orderingRuleID);
-                  throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
-                      message);
-                }
-                break;
-
-              case TYPE_REVERSE_ORDER:
-                ascending = ! reader.readBoolean();
-                break;
-
-              default:
-                Message message = INFO_SORTREQ_CONTROL_INVALID_SEQ_ELEMENT_TYPE.
-                    get(byteToHex(reader.peekType()));
-                throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
-                    message);
+              Message message =
+                  INFO_SORTREQ_CONTROL_UNDEFINED_ORDERING_RULE.
+                      get(orderingRuleID);
+              throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
+                  message);
             }
           }
+          if(reader.hasNextElement() &&
+              reader.peekType() == TYPE_REVERSE_ORDER)
+          {
+            ascending = ! reader.readBoolean();
+          }
+          reader.readEndSequence();
 
           if ((orderingRule == null) &&
               (attrType.getOrderingMatchingRule() == null))
@@ -167,6 +158,7 @@
 
           sortKeys.add(new SortKey(attrType, ascending, orderingRule));
         }
+        reader.readEndSequence();
 
         return new ServerSideSortRequestControl(isCritical,
             new SortOrder(sortKeys.toArray(new SortKey[0])));
diff --git a/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java b/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java
index 6f8377d..e866da7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2008 Sun Microsystems, Inc.
+ *      Copyright 2008-2009 Sun Microsystems, Inc.
  */
 
 package org.opends.server.crypto;
@@ -168,24 +168,15 @@
     {
       ASN1Reader reader = ASN1.getReader(requestValue);
       reader.readStartSequence();
-      while(reader.hasNextElement())
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_SYMMETRIC_KEY_ELEMENT)
       {
-        switch (reader.peekType())
-        {
-          case TYPE_SYMMETRIC_KEY_ELEMENT:
-            requestSymmetricKey = reader.readOctetStringAsString();
-            break;
-
-          case TYPE_INSTANCE_KEY_ID_ELEMENT:
-            instanceKeyID = reader.readOctetStringAsString();
-            break;
-
-          default:
-            Message message = ERR_GET_SYMMETRIC_KEY_INVALID_TYPE.get(
-                 StaticUtils.byteToHex(reader.peekType()));
-            operation.appendErrorMessage(message);
-            return;
-        }
+        requestSymmetricKey = reader.readOctetStringAsString();
+      }
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_INSTANCE_KEY_ID_ELEMENT)
+      {
+        instanceKeyID = reader.readOctetStringAsString();
       }
       reader.readEndSequence();
     }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
index a22a179..953d76b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -249,33 +249,20 @@
       {
         ASN1Reader reader = ASN1.getReader(requestValue);
         reader.readStartSequence();
-        while(reader.hasNextElement())
+        if(reader.hasNextElement() &&
+            reader.peekType() == TYPE_PASSWORD_MODIFY_USER_ID)
         {
-          switch (reader.peekType())
-          {
-            case TYPE_PASSWORD_MODIFY_USER_ID:
-              userIdentity = reader.readOctetString();
-              break;
-            case TYPE_PASSWORD_MODIFY_OLD_PASSWORD:
-              oldPassword = reader.readOctetString();
-              break;
-            case TYPE_PASSWORD_MODIFY_NEW_PASSWORD:
-              newPassword = reader.readOctetString();
-              break;
-            default:
-              // Its ok if we encounter unrecognized trailing tags
-              reader.skipElement();
-              if(reader.hasNextElement())
-              {
-                operation.setResultCode(ResultCode.PROTOCOL_ERROR);
-
-
-                operation.appendErrorMessage(
-                    ERR_EXTOP_PASSMOD_ILLEGAL_REQUEST_ELEMENT_TYPE.get(
-                        byteToHex(reader.peekType())));
-                return;
-              }
-          }
+          userIdentity = reader.readOctetString();
+        }
+        if(reader.hasNextElement() &&
+            reader.peekType() == TYPE_PASSWORD_MODIFY_OLD_PASSWORD)
+        {
+          oldPassword = reader.readOctetString();
+        }
+        if(reader.hasNextElement() &&
+            reader.peekType() == TYPE_PASSWORD_MODIFY_NEW_PASSWORD)
+        {
+          newPassword = reader.readOctetString();
         }
         reader.readEndSequence();
       }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteSequenceReader.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteSequenceReader.java
index 7d8d608..921a4fc 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteSequenceReader.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteSequenceReader.java
@@ -36,12 +36,17 @@
 import org.opends.server.types.ByteSequenceReader;
 import org.opends.server.types.ByteString;
 import org.opends.server.types.ByteStringBuilder;
+import org.opends.server.loggers.debug.DebugTracer;
+import static org.opends.server.loggers.debug.DebugLogger.getTracer;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
 
 /**
  * An ASN.1 reader that reads from a {@link ByteSequenceReader}.
  */
 final class ASN1ByteSequenceReader implements ASN1Reader
 {
+  private static final DebugTracer TRACER = getTracer();
+
   private int state = ELEMENT_READ_STATE_NEED_TYPE;
   private byte peekType = 0;
   private int peekLength = -1;
@@ -473,11 +478,10 @@
       throw new ASN1Exception(message);
     }
 
-    if(reader.remaining() > 0)
+    if(reader.remaining() > 0 && debugEnabled())
     {
-      Message message =
-          ERR_ASN1_SEQUENCE_READ_NOT_ENDED.get(reader.remaining(), peekLength);
-      throw new ASN1Exception(message);
+      TRACER.debugWarning("Ignoring %d unused trailing bytes in " +
+          "ASN.1 SEQUENCE", reader.remaining());
     }
 
     reader = readerStack.removeFirst();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1InputStreamReader.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1InputStreamReader.java
index 56e838c..f3a7e86 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1InputStreamReader.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1InputStreamReader.java
@@ -765,14 +765,26 @@
       throw new ASN1Exception(message);
     }
 
-    // If not everything was read, throw error
+    // Ignore all unused trailing components.
     SizeLimitInputStream subSq = (SizeLimitInputStream)in;
     if(subSq.getSizeLimit() - subSq.getBytesRead() > 0)
     {
-      Message message =
-          ERR_ASN1_SEQUENCE_READ_NOT_ENDED.get(subSq.getSizeLimit() -
-              subSq.getBytesRead(), subSq.getSizeLimit());
-      throw new ASN1Exception(message);
+      if(debugEnabled())
+      {
+        TRACER.debugWarning("Ignoring %d unused trailing bytes in " +
+            "ASN.1 SEQUENCE", subSq.getSizeLimit() - subSq.getBytesRead());
+      }
+
+      try
+      {
+        subSq.skip(subSq.getSizeLimit() - subSq.getBytesRead());
+      }
+      catch(IOException ioe)
+      {
+        Message message =
+            ERR_ASN1_READ_ERROR.get(ioe.toString());
+        throw new ASN1Exception(message, ioe);
+      }
     }
 
     in = streamStack.removeFirst();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPReader.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPReader.java
index c00c468..9133f2b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPReader.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPReader.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.protocols.ldap;
 
@@ -39,7 +39,6 @@
 
 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
 import static org.opends.server.loggers.debug.DebugLogger.getTracer;
-import static org.opends.server.util.StaticUtils.byteToHex;
 
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
@@ -629,9 +628,9 @@
       throw new LDAPException(PROTOCOL_ERROR, message, e);
     }
 
-    ByteString    simplePassword  = null;
-    String             saslMechanism = null;
-    ByteString    saslCredentials = null;
+    ByteString simplePassword  = null;
+    String     saslMechanism   = null;
+    ByteString saslCredentials = null;
     switch (type)
     {
       case TYPE_AUTHENTICATION_SIMPLE:
@@ -797,59 +796,53 @@
 
     try
     {
-      while(reader.hasNextElement())
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_REFERRAL_SEQUENCE)
       {
-        switch(reader.peekType())
+        try
         {
-          case TYPE_REFERRAL_SEQUENCE:
-            try
-            {
-              reader.readStartSequence();
-              referralURLs = new ArrayList<String>();
+          reader.readStartSequence();
+          referralURLs = new ArrayList<String>();
 
-              while(reader.hasNextElement())
-              {
-                referralURLs.add(reader.readOctetStringAsString());
-              }
-              reader.readEndSequence();
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
+          // Should have at least 1.
+          do
+          {
+            referralURLs.add(reader.readOctetStringAsString());
+          }
+          while(reader.hasNextElement());
+          reader.readEndSequence();
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
 
-              Message message =
-                  ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e));
-              throw new LDAPException(PROTOCOL_ERROR, message, e);
-            }
+          Message message =
+              ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e));
+          throw new LDAPException(PROTOCOL_ERROR, message, e);
+        }
+      }
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_SERVER_SASL_CREDENTIALS)
+      {
+        try
+        {
+          serverSASLCredentials =
+              reader.readOctetString();
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
 
-            break;
-          case TYPE_SERVER_SASL_CREDENTIALS:
-            try
-            {
-              serverSASLCredentials =
-                  reader.readOctetString();
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
-
-              Message message =
-                  ERR_LDAP_BIND_RESULT_DECODE_SERVER_SASL_CREDENTIALS.
-                      get(String.valueOf(e));
-              throw new LDAPException(PROTOCOL_ERROR, message, e);
-            }
-
-            break;
-          default:
-            Message message =
-                ERR_LDAP_BIND_RESULT_DECODE_INVALID_TYPE.get(reader.peekType());
-            throw new LDAPException(PROTOCOL_ERROR, message);
+          Message message =
+              ERR_LDAP_BIND_RESULT_DECODE_SERVER_SASL_CREDENTIALS.
+                  get(String.valueOf(e));
+          throw new LDAPException(PROTOCOL_ERROR, message, e);
         }
       }
     }
@@ -1519,74 +1512,68 @@
 
     try
     {
-      while(reader.hasNextElement())
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_REFERRAL_SEQUENCE)
       {
-        switch(reader.peekType())
+        try
         {
-          case TYPE_REFERRAL_SEQUENCE:
-            try
-            {
-              reader.readStartSequence();
-              referralURLs = new ArrayList<String>();
+          reader.readStartSequence();
+          referralURLs = new ArrayList<String>();
 
-              while(reader.hasNextElement())
-              {
-                referralURLs.add(reader.readOctetStringAsString());
-              }
-              reader.readEndSequence();
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
+          while(reader.hasNextElement())
+          {
+            referralURLs.add(reader.readOctetStringAsString());
+          }
+          reader.readEndSequence();
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
 
-              Message message =
-                  ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e));
-              throw new LDAPException(PROTOCOL_ERROR, message, e);
-            }
-            break;
-          case TYPE_EXTENDED_RESPONSE_OID:
-            try
-            {
-              oid = reader.readOctetStringAsString();
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
+          Message message =
+              ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e));
+          throw new LDAPException(PROTOCOL_ERROR, message, e);
+        }
+      }
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_EXTENDED_RESPONSE_OID)
+      {
+        try
+        {
+          oid = reader.readOctetStringAsString();
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
 
-              Message message =
-                  ERR_LDAP_EXTENDED_RESULT_DECODE_OID.get(String.valueOf(e));
-              throw new LDAPException(PROTOCOL_ERROR, message, e);
-            }
+          Message message =
+              ERR_LDAP_EXTENDED_RESULT_DECODE_OID.get(String.valueOf(e));
+          throw new LDAPException(PROTOCOL_ERROR, message, e);
+        }
+      }
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_EXTENDED_RESPONSE_VALUE)
+      {
+        try
+        {
+          value = reader.readOctetString();
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
 
-            break;
-          case TYPE_EXTENDED_RESPONSE_VALUE:
-            try
-            {
-              value = reader.readOctetString();
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
-
-              Message message =
-                  ERR_LDAP_EXTENDED_RESULT_DECODE_VALUE.get(String.valueOf(e));
-              throw new LDAPException(PROTOCOL_ERROR, message, e);
-            }
-
-            break;
-          default:
-            Message message = ERR_LDAP_EXTENDED_RESULT_DECODE_INVALID_TYPE.get(
-                reader.peekType());
-            throw new LDAPException(PROTOCOL_ERROR, message);
+          Message message =
+              ERR_LDAP_EXTENDED_RESULT_DECODE_VALUE.get(String.valueOf(e));
+          throw new LDAPException(PROTOCOL_ERROR, message, e);
         }
       }
     }
@@ -1654,54 +1641,47 @@
 
     try
     {
-      while(reader.hasNextElement())
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_INTERMEDIATE_RESPONSE_OID)
       {
-        switch(reader.peekType())
+        try
         {
-          case TYPE_INTERMEDIATE_RESPONSE_OID:
-            try
-            {
-              if(reader.hasNextElement())
-              {
-                oid = reader.readOctetStringAsString();
-              }
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
+          if(reader.hasNextElement())
+          {
+            oid = reader.readOctetStringAsString();
+          }
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
 
-              Message message =
-                  ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_OID.get(
-                      e.getMessage());
-              throw new LDAPException(PROTOCOL_ERROR, message);
-            }
-            break;
-          case TYPE_INTERMEDIATE_RESPONSE_VALUE:
-            try
-            {
-              value = reader.readOctetString();
-            }
-            catch (Exception e)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-              }
+          Message message =
+              ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_OID.get(
+                  e.getMessage());
+          throw new LDAPException(PROTOCOL_ERROR, message);
+        }
+      }
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_INTERMEDIATE_RESPONSE_VALUE)
+      {
+        try
+        {
+          value = reader.readOctetString();
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e);
+          }
 
-              Message message =
-                  ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_VALUE.
-                      get(e.getMessage());
-              throw new LDAPException(PROTOCOL_ERROR, message);
-            }
-            break;
-          default:
-            Message message =
-                ERR_LDAP_INTERMEDIATE_RESPONSE_INVALID_ELEMENT_TYPE.get(
-                    byteToHex(reader.peekType()));
-            throw new LDAPException(PROTOCOL_ERROR, message);
+          Message message =
+              ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_VALUE.
+                  get(e.getMessage());
+          throw new LDAPException(PROTOCOL_ERROR, message);
         }
       }
     }
@@ -2754,10 +2734,12 @@
     ArrayList<String> referralURLs = new ArrayList<String>();
     try
     {
-      while(reader.hasNextElement())
+      // Should have atleast 1 URL.
+      do
       {
         referralURLs.add(reader.readOctetStringAsString());
       }
+      while(reader.hasNextElement());
     }
     catch (Exception e)
     {
@@ -2904,48 +2886,42 @@
     ByteString value = null;
     try
     {
-      while(reader.hasNextElement())
+      if(reader.hasNextElement() &&
+          reader.peekType() == UNIVERSAL_BOOLEAN_TYPE)
       {
-        switch(reader.peekType())
+        try
         {
-          case UNIVERSAL_BOOLEAN_TYPE:
-            try
-            {
-              isCritical = reader.readBoolean();
-            }
-            catch (Exception e2)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e2);
-              }
+          isCritical = reader.readBoolean();
+        }
+        catch (Exception e2)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e2);
+          }
 
-              Message message =
-                  ERR_LDAP_CONTROL_DECODE_CRITICALITY.get(String.valueOf(e2));
-              throw new LDAPException(PROTOCOL_ERROR, message, e2);
-            }
-            break;
-          case UNIVERSAL_OCTET_STRING_TYPE:
-            try
-            {
-              value = reader.readOctetString();
-            }
-            catch (Exception e2)
-            {
-              if (debugEnabled())
-              {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e2);
-              }
+          Message message =
+              ERR_LDAP_CONTROL_DECODE_CRITICALITY.get(String.valueOf(e2));
+          throw new LDAPException(PROTOCOL_ERROR, message, e2);
+        }
+      }
+      if(reader.hasNextElement() &&
+          reader.peekType() == UNIVERSAL_OCTET_STRING_TYPE)
+      {
+        try
+        {
+          value = reader.readOctetString();
+        }
+        catch (Exception e2)
+        {
+          if (debugEnabled())
+          {
+            TRACER.debugCaught(DebugLogLevel.ERROR, e2);
+          }
 
-              Message message =
-                  ERR_LDAP_CONTROL_DECODE_VALUE.get(String.valueOf(e2));
-              throw new LDAPException(PROTOCOL_ERROR, message, e2);
-            }
-            break;
-          default:
-            Message message =
-                ERR_LDAP_CONTROL_DECODE_INVALID_TYPE.get(reader.peekType());
-            throw new LDAPException(PROTOCOL_ERROR, message);
+          Message message =
+              ERR_LDAP_CONTROL_DECODE_VALUE.get(String.valueOf(e2));
+          throw new LDAPException(PROTOCOL_ERROR, message, e2);
         }
       }
     }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/RawFilter.java b/opendj-sdk/opends/src/server/org/opends/server/types/RawFilter.java
index 4ee48b0..840549d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/RawFilter.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/RawFilter.java
@@ -636,10 +636,12 @@
     try
     {
       reader.readStartSequence();
-      while(reader.hasNextElement())
+      // Should have atleast 1 filter.
+      do
       {
         filterComponents.add(LDAPFilter.decode(reader));
       }
+      while(reader.hasNextElement());
       reader.readEndSequence();
     }
     catch (LDAPException le)
@@ -915,35 +917,25 @@
     ArrayList<ByteString> subAnyElements = null;
     try
     {
-      while(reader.hasNextElement())
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_SUBINITIAL)
       {
-        switch (reader.peekType())
-        {
-          case TYPE_SUBINITIAL:
-            subInitialElement = reader.readOctetString();
-            break;
-          case TYPE_SUBFINAL:
-            subFinalElement = reader.readOctetString();
-            break;
-          case TYPE_SUBANY:
-            if (subAnyElements == null)
-            {
-              subAnyElements = new ArrayList<ByteString>();
-            }
-
-            subAnyElements.add(reader.readOctetString());
-            break;
-          default:
-            Message message =
-                ERR_LDAP_FILTER_DECODE_SUBSTRING_INVALID_SUBTYPE.
-                  get(reader.peekType());
-            throw new LDAPException(PROTOCOL_ERROR, message);
-        }
+        subInitialElement = reader.readOctetString();
       }
-    }
-    catch (LDAPException le)
-    {
-      throw le;
+      while(reader.hasNextElement() &&
+          reader.peekType() == TYPE_SUBANY)
+      {
+        if(subAnyElements == null)
+        {
+          subAnyElements = new ArrayList<ByteString>();
+        }
+        subAnyElements.add(reader.readOctetString());
+      }
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_SUBFINAL)
+      {
+        subFinalElement = reader.readOctetString();
+      }
     }
     catch (Exception e)
     {
@@ -1066,39 +1058,27 @@
     }
 
 
-    ByteString assertionValue = null;
+    ByteString assertionValue;
     boolean    dnAttributes   = false;
     String     attributeType  = null;
     String     matchingRuleID = null;
     try
     {
-      while(reader.hasNextElement())
+      if(reader.peekType() == TYPE_MATCHING_RULE_ID)
       {
-        switch (reader.peekType())
-        {
-          case TYPE_MATCHING_RULE_ID:
-            matchingRuleID = reader.readOctetStringAsString();
-            break;
-          case TYPE_MATCHING_RULE_TYPE:
-            attributeType = reader.readOctetStringAsString();
-            break;
-          case TYPE_MATCHING_RULE_VALUE:
-            assertionValue = reader.readOctetString();
-            break;
-          case TYPE_MATCHING_RULE_DN_ATTRIBUTES:
-            dnAttributes = reader.readBoolean();
-            break;
-          default:
-            Message message =
-                ERR_LDAP_FILTER_DECODE_EXTENSIBLE_INVALID_TYPE.
-                  get(reader.peekType());
-            throw new LDAPException(PROTOCOL_ERROR, message);
-        }
+        matchingRuleID = reader.readOctetStringAsString();
       }
-    }
-    catch (LDAPException le)
-    {
-      throw le;
+      if(matchingRuleID == null ||
+          reader.peekType() == TYPE_MATCHING_RULE_TYPE)
+      {
+        attributeType = reader.readOctetStringAsString();
+      }
+      assertionValue = reader.readOctetString();
+      if(reader.hasNextElement() &&
+          reader.peekType() == TYPE_MATCHING_RULE_DN_ATTRIBUTES)
+      {
+        dnAttributes = reader.readBoolean();
+      }
     }
     catch (Exception e)
     {
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java
index 23cc4fe..06ffef2 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2008 Sun Microsystems, Inc.
+ *      Copyright 2008-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.controls;
 
@@ -242,7 +242,7 @@
    *
    * @throws  Exception  If an unexpected problem occurs.
    */
-  @Test(expectedExceptions = { DirectoryException.class })
+  @Test
   public void testDecodeControlValueMultiElementSequence()
          throws Exception
   {
@@ -255,7 +255,9 @@
     LDAPControl c =
         new LDAPControl(OID_PROXIED_AUTH_V1, true, bsb.toByteString());
 
-    ProxiedAuthV1Control.DECODER.decode(c.isCritical(), c.getValue());
+    assertEquals(ByteString.valueOf("uid=element1,o=test"),
+        ProxiedAuthV1Control.DECODER.decode(c.isCritical(),
+            c.getValue()).getRawAuthorizationDN());
   }
 
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ReaderTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ReaderTestCase.java
index 668b566..336afc5 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ReaderTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/ASN1ReaderTestCase.java
@@ -752,21 +752,20 @@
   }
 
   /**
-   * Tests to make sure not reading all elements in a sub sequence can be
-   * detected.
+   * Tests to make sure trailing components are ignored if not used.
    *
    * @throws  Exception  If an unexpected problem occurs.
    */
-  @Test(expectedExceptions = { ASN1Exception.class })
+  @Test
   public void testDecodeSequenceIncompleteRead()
       throws Exception
   {
     // An ASN.1 sequence of booleans missing one boolean element at the end
-    byte[] b = new byte[] { 0x30, 0x06, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00 };
+    byte[] b = new byte[] { 0x30, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 };
     ASN1Reader reader = getReader(b, 0);
     reader.readStartSequence();
-    reader.readBoolean();
     reader.readEndSequence();
+    assertFalse(reader.readBoolean());
   }
 
   /**
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestBindResponseProtocolOp.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestBindResponseProtocolOp.java
index ed90701..0c222d1 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestBindResponseProtocolOp.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestBindResponseProtocolOp.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.protocols.ldap;
 
@@ -96,19 +96,32 @@
       LDAPReader.readProtocolOp(reader);
     }
 
-    @Test (expectedExceptions = LDAPException.class)
-    public void testBindResponseTooMany() throws Exception {      
+  /**
+   * Test to ensure trailing unrecognized components are ignored.
+   */
+    @Test
+    public void testBindResponseTooMany() throws Exception {
+      DN responseDn = DN.decode(dn);
+
       ByteStringBuilder bsb = new ByteStringBuilder();
       ASN1Writer writer = ASN1.getWriter(bsb);
       writer.writeStartSequence(OP_TYPE_BIND_RESPONSE);
       writer.writeInteger(okCode.getIntValue());
-      writer.writeOctetString((String)null);
-      writer.writeOctetString((String)null);
+      writer.writeOctetString(responseDn.toString());
+      writer.writeOctetString(message.toString());
       writer.writeBoolean(true);
       writer.writeEndSequence();
 
       ASN1Reader reader = ASN1.getReader(bsb.toByteString());
-      LDAPReader.readProtocolOp(reader);
+      ProtocolOp protocolOp = LDAPReader.readProtocolOp(reader);
+
+      assertTrue(protocolOp instanceof BindResponseProtocolOp);
+      BindResponseProtocolOp bindResponse = (BindResponseProtocolOp)protocolOp;
+      assertTrue(bindResponse.getResultCode() == okCode.getIntValue());
+      assertTrue(bindResponse.getMatchedDN().toNormalizedString().equals(responseDn.toNormalizedString()));
+      assertTrue(bindResponse.getErrorMessage().toString().equals(message.toString()));
+      assertNull(bindResponse.getReferralURLs());
+      assertNull(bindResponse.getServerSASLCredentials());
     }
 
     @Test (expectedExceptions = LDAPException.class)
@@ -125,7 +138,11 @@
       LDAPReader.readProtocolOp(reader);
     }
 
-    @Test (expectedExceptions = LDAPException.class)
+  /**
+   * Test to ensure trailing unrecognized components are ignored
+   * without generating an error.
+   */
+    @Test
     public void testBindResponseBadReferral() throws Exception {
       DN responseDn = DN.decode(dn);
       ByteString serverSASLCredentials =
@@ -143,7 +160,15 @@
       writer.writeEndSequence();
 
       ASN1Reader reader = ASN1.getReader(bsb.toByteString());
-      LDAPReader.readProtocolOp(reader);
+      ProtocolOp protocolOp = LDAPReader.readProtocolOp(reader);
+
+      assertTrue(protocolOp instanceof BindResponseProtocolOp);
+      BindResponseProtocolOp bindResponse = (BindResponseProtocolOp)protocolOp;
+      assertTrue(bindResponse.getResultCode() == okCode.getIntValue());
+      assertTrue(bindResponse.getMatchedDN().toNormalizedString().equals(responseDn.toNormalizedString()));
+      assertTrue(bindResponse.getErrorMessage().toString().equals(message.toString()));
+      assertNull(bindResponse.getReferralURLs());
+      assertNull(bindResponse.getServerSASLCredentials());
     }
 
     @Test
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestSearchProtocolOp.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestSearchProtocolOp.java
index ff78795..b76beb2 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestSearchProtocolOp.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/TestSearchProtocolOp.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 
 
@@ -137,7 +137,11 @@
     LDAPReader.readProtocolOp(reader);
   }
 
-  @Test (expectedExceptions = LDAPException.class)
+  /**
+   * This should succeed since we are ignoring trailing SEQUENCE
+   * components.
+   */
+  @Test
   public void testInvalidSearchRequestTooManyElements() throws Exception
   {
     ByteStringBuilder builder = new ByteStringBuilder();
@@ -162,7 +166,27 @@
     writer.writeEndSequence();
 
     ASN1Reader reader = ASN1.getReader(builder.toByteString());
-    LDAPReader.readProtocolOp(reader);
+
+    ProtocolOp decodedProtocolOp = LDAPReader.readProtocolOp(reader);
+
+    // Make sure the protocol op is the correct type.
+    assertTrue(decodedProtocolOp instanceof SearchRequestProtocolOp);
+    SearchRequestProtocolOp searchOp =
+         (SearchRequestProtocolOp)decodedProtocolOp;
+
+    // Check that the fields have not been changed during encode and decode.
+    assertTrue(baseDN.equals(searchOp.getBaseDN()));
+    assertTrue(scope.equals(searchOp.getScope()));
+    assertTrue(dereferencePolicy.
+         equals(searchOp.getDereferencePolicy()));
+    assertTrue(sizeLimit == searchOp.getSizeLimit());
+    assertTrue(timeLimit == searchOp.getTimeLimit());
+    assertTrue(filter.toString().equals(
+         searchOp.getFilter().toString()));
+    // Check that the attributes are in the correct order (comparing the sets
+    // directly does not guarantee this).
+    assertTrue(Arrays.equals(attributes.toArray(),
+                             searchOp.getAttributes().toArray()));
   }
 
   @Test (expectedExceptions = LDAPException.class)

--
Gitblit v1.10.0