mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
24.55.2006 d3c0e4742ffd53819e05c56b5c468fb1f5d254f8
Update the bit string attribute syntax and the corresponding test case to
remove convenience methods for creating and decoding bit string values. These
methods aren't really very useful for anything, and they don't properly deal
with bit strings where the number of bits is not a multiple of eight.

The updates to the test code were provided by Benjamin Damm.

OpenDS Issue Number: 726
2 files modified
201 ■■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/schema/BitStringSyntax.java 185 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/BitStringSyntaxTest.java 16 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/schema/BitStringSyntax.java
@@ -36,13 +36,9 @@
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
import org.opends.server.types.ResultCode;
import static org.opends.server.loggers.Debug.*;
import static org.opends.server.loggers.Error.*;
@@ -291,186 +287,5 @@
    // If we've gotten here, then everything is fine.
    return true;
  }
  /**
   * Retrieves an attribute value containing a bit string representation of the
   * provided value.
   *
   * @param  b  The byte for which to retrieve the bit string value.
   *
   * @return  The attribute value created from the provided byte.
   */
  public static AttributeValue createBitStringValue(byte b)
  {
    assert debugEnter(CLASS_NAME, "createBitStringValue", String.valueOf(b));
    String bitString = "'" + byteToBinary(b) + "'B";
    return new AttributeValue(new ASN1OctetString(bitString),
                              new ASN1OctetString(bitString));
  }
  /**
   * Retrieves an attribute value containing a bit string representation of the
   * provided value.
   *
   * @param  b  The byte array for which to retrieve the bit string value.
   *
   * @return  The attribute value created from the provided byte array.
   */
  public static AttributeValue createBitStringValue(byte[] b)
  {
    assert debugEnter(CLASS_NAME, "createBitStringValue", String.valueOf(b));
    int    length;
    String bitString;
    if ((b == null) || ((length = b.length) == 0))
    {
      bitString = "''B";
    }
    else
    {
      StringBuilder buffer = new StringBuilder(3 + (8*length));
      buffer.append("'");
      for (int i=0; i < length; i++)
      {
        buffer.append(byteToBinary(b[i]));
      }
      buffer.append("'B");
      bitString = buffer.toString();
    }
    return new AttributeValue(new ASN1OctetString(bitString),
                              new ASN1OctetString(bitString));
  }
  /**
   * Decodes the provided normalized value as a bit string and retrieves a byte
   * array containing its binary representation.  Note that if the bit string
   * contained in the provided value has a length that is not a multiple of
   * eight, then the final byte will be padded with <B>leading</B> zeros, so
   * the bit string value '1111111111'B will be returned as the byte array
   * { 11111111, 00000011 }.
   *
   * @param  normalizedValue  The normalized bit string value to decode to a
   *                          byte array.
   *
   * @return  The byte array containing the binary representation of the
   *          provided bit string value.
   *
   * @throws  DirectoryException  If the provided value cannot be parsed as a
   *                              valid bit string.
   */
  public static byte[] decodeBitStringValue(ByteString normalizedValue)
         throws DirectoryException
  {
    assert debugEnter(CLASS_NAME, "decodeBitStringValue",
                      String.valueOf(normalizedValue));
    String valueString = normalizedValue.stringValue();
    int length = valueString.length();
    if (length < 3)
    {
      int    msgID   = MSGID_ATTR_SYNTAX_BIT_STRING_TOO_SHORT;
      String message = getMessage(msgID, valueString);
      throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                                   message, msgID);
    }
    if ((valueString.charAt(0) != '\'') ||
        (valueString.charAt(length-2) != '\'') ||
        (valueString.charAt(length-1) != 'B'))
    {
      int pos;
      if (valueString.charAt(0) != '\'')
      {
        pos = 0;
      }
      else if (valueString.charAt(length-2) != '\'')
      {
        pos = length - 2;
      }
      else
      {
        pos = length - 1;
      }
      int    msgID   = MSGID_ATTR_SYNTAX_BIT_STRING_NOT_QUOTED;
      String message = getMessage(msgID, valueString);
      throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                                   message, msgID);
    }
    int numBits      = length - 3;
    int numFullBytes = numBits / 8;
    int numBytes     = numFullBytes;
    int numExtraBits = (numBits % 8);
    if (numExtraBits != 0)
    {
      numBytes++;
    }
    byte[] b = new byte[numBytes];
    int pos = 1;
    for (int i=0; i < numFullBytes; i++)
    {
      b[i] = 0x00;
      for (int j=0; j < 8; j++)
      {
        char c = valueString.charAt(pos++);
        if (c == '0')
        {
          b[i] <<= 1;
        }
        else if (c == '1')
        {
          b[i] = (byte) ((b[i] << 1) | 0x01);
        }
        else
        {
          int    msgID   = MSGID_ATTR_SYNTAX_BIT_STRING_INVALID_BIT;
          String message = getMessage(msgID, valueString, c);
          throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                                       message, msgID);
        }
      }
    }
    if (numExtraBits > 0)
    {
      b[numFullBytes] = 0x00;
      for (int i=0; i < numExtraBits; i++)
      {
        char c = valueString.charAt(pos++);
        if (c == '0')
        {
          b[numFullBytes] <<= 1;
        }
        else if (c == '1')
        {
          b[numFullBytes] = (byte) ((b[numFullBytes] << 1) | 0x01);
        }
        else
        {
          int    msgID   = MSGID_ATTR_SYNTAX_BIT_STRING_INVALID_BIT;
          String message = getMessage(msgID, valueString, c);
          throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                                       message, msgID);
        }
      }
    }
    return b;
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/BitStringSyntaxTest.java
@@ -29,7 +29,6 @@
import static org.testng.Assert.*;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.api.EqualityMatchingRule;
import org.opends.server.config.ConfigEntry;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
@@ -91,21 +90,6 @@
    if (liveResult != result)
      fail(syntax + ".valueIsAcceptable gave bad result for " + value + 
          "reason : " + reason);
    if (result == true)
    {
      byte[] decodedValue =
        BitStringSyntax.decodeBitStringValue(byteStringValue);
      ByteString newValue =
        BitStringSyntax.createBitStringValue(decodedValue).getNormalizedValue();
      EqualityMatchingRule matchingRule = syntax.getEqualityMatchingRule();
     /* disabled because it currently fails
      * see issue 726
      *
      * assertTrue(matchingRule.areEqual(byteStringValue, newValue));
      */
    }
    // call the getters
    syntax.getApproximateMatchingRule();