Search in sources :

Example 21 with Asn1Container

use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.

the class Asn1Decoder method isTLVDecoded.

/**
 * Check if the TLV tree is fully decoded
 *
 * @param container The container
 * @return <code>true</code> if the TLV has been decoded
 */
private boolean isTLVDecoded(Asn1Container container) {
    TLV current = container.getCurrentTLV();
    TLV parent = current.getParent();
    while (parent != null) {
        if (parent.getExpectedLength() != 0) {
            return false;
        }
        parent = parent.getParent();
    }
    BerValue value = current.getValue();
    if ((value != null) && (value.getData() != null)) {
        return current.getExpectedLength() == value.getData().length;
    } else {
        return current.getExpectedLength() == 0;
    }
}
Also used : BerValue(org.apache.directory.api.asn1.ber.tlv.BerValue) TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 22 with Asn1Container

use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.

the class Asn1Decoder method treatValuePendingState.

/**
 * Treat a pending Value when we get more bytes in the buffer.
 *
 * @param stream The ByteBuffer containing the PDU to decode
 * @param container The container that stores the current state,
 * the result and other informations.
 * @return <code>MORE</code> if some bytes remain in the buffer when the
 * value has been decoded, <code>END</code> if whe still need to get some
 * more bytes.
 */
private boolean treatValuePendingState(ByteBuffer stream, Asn1Container container) {
    TLV currentTlv = container.getCurrentTLV();
    int length = currentTlv.getLength();
    int currentLength = currentTlv.getValue().getCurrentLength();
    int nbBytes = stream.remaining();
    if ((currentLength + nbBytes) < length) {
        currentTlv.getValue().addData(stream);
        container.setState(TLVStateEnum.VALUE_STATE_PENDING);
        return END;
    } else {
        int remaining = length - currentLength;
        byte[] data = new byte[remaining];
        stream.get(data, 0, remaining);
        currentTlv.getValue().addData(data);
        container.setState(TLVStateEnum.TLV_STATE_DONE);
        return MORE;
    }
}
Also used : TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 23 with Asn1Container

use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.

the class Asn1Decoder method treatLengthEndState.

/**
 * The Length is fully decoded. We have to call an action to check the size.
 *
 * @param container The container that stores the current state,
 * the result and other informations.
 * @throws DecoderException Thrown if anything went wrong
 */
private void treatLengthEndState(Asn1Container container) throws DecoderException {
    TLV tlv = container.getCurrentTLV();
    if (tlv == null) {
        String msg = I18n.err(I18n.ERR_01002_TLV_NULL);
        LOG.error(msg);
        throw new DecoderException(msg);
    }
    int length = tlv.getLength();
    // We will check the length here. What we must control is
    // that the enclosing constructed TLV expected length is not
    // exceeded by the current TLV.
    TLV parentTLV = container.getParentTLV();
    if (IS_DEBUG) {
        LOG.debug(I18n.msg(I18n.MSG_01003_PARENT_LENGTH, getParentLength(parentTLV)));
    }
    if (parentTLV == null) {
        // This is the first TLV, so we can't check anything. We will
        // just store this TLV as the root of the PDU
        tlv.setExpectedLength(length);
        container.setParentTLV(tlv);
        if (IS_DEBUG) {
            LOG.debug(I18n.msg(I18n.MSG_01004_ROOT_TLV, Integer.valueOf(length)));
        }
    } else {
        // We have a parent, so we will check that its expected length is
        // not exceeded.
        int expectedLength = parentTLV.getExpectedLength();
        int currentLength = tlv.getSize();
        if (expectedLength < currentLength) {
            // current TLV. This is an error...
            if (IS_DEBUG) {
                LOG.debug(I18n.msg(I18n.MSG_01005_TLV, Integer.valueOf(expectedLength), Integer.valueOf(currentLength)));
            }
            throw new DecoderException(I18n.err(I18n.ERR_01003_VALUE_LENGTH_ABOVE_EXPECTED_LENGTH, Integer.valueOf(currentLength), Integer.valueOf(expectedLength)));
        }
        // completed.
        if (expectedLength == currentLength) {
            parentTLV.setExpectedLength(0);
            // to the parent's parent TLV.
            if (tlv.isConstructed()) {
                // the parents which length is null.
                if (length == 0) {
                    // is not null, and it will become the new parent TLV
                    while (parentTLV != null) {
                        if (parentTLV.getExpectedLength() != 0) {
                            // stop the recursion right here
                            break;
                        } else {
                            parentTLV = parentTLV.getParent();
                        }
                    }
                    container.setParentTLV(parentTLV);
                } else {
                    // The new Parent TLV is this Constructed TLV
                    container.setParentTLV(tlv);
                }
                tlv.setParent(parentTLV);
                tlv.setExpectedLength(length);
            } else {
                tlv.setExpectedLength(length);
                // a tlv which is not complete.
                while (parentTLV != null) {
                    if (parentTLV.getExpectedLength() != 0) {
                        // stop the recursion right here
                        break;
                    } else {
                        parentTLV = parentTLV.getParent();
                    }
                }
                container.setParentTLV(parentTLV);
            }
        } else {
            // Renew the expected Length.
            parentTLV.setExpectedLength(expectedLength - currentLength);
            tlv.setExpectedLength(length);
            if (tlv.isConstructed()) {
                // We have a constructed tag, so we must switch the
                // parentTLV
                tlv.setParent(parentTLV);
                container.setParentTLV(tlv);
            }
        }
    }
    if (IS_DEBUG) {
        LOG.debug(I18n.msg(I18n.MSG_01006_LENGTH_DECODED, Integer.valueOf(length)));
    }
    if (length == 0) {
        // The length is 0, so we can't expect a value.
        container.setState(TLVStateEnum.TLV_STATE_DONE);
    } else {
        // Go ahead and decode the value part
        container.setState(TLVStateEnum.VALUE_STATE_START);
    }
}
Also used : DecoderException(org.apache.directory.api.asn1.DecoderException) TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 24 with Asn1Container

use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.

the class Asn1Decoder method treatLengthPendingState.

/**
 * This function is called when a Length is in the process of being decoded,
 * but the lack of bytes in the buffer stopped the process.
 *
 * @param stream The ByteBuffer containing the PDU to decode
 * @param container The container that stores the current state,
 * the result and other informations.
 * @return <code>true</code> if there are more bytes to read, <code>false
 * </code> otherwise
 */
private boolean treatLengthPendingState(ByteBuffer stream, Asn1Container container) {
    if (stream.hasRemaining()) {
        TLV tlv = container.getCurrentTLV();
        int length = tlv.getLength();
        while (tlv.getLengthBytesRead() < tlv.getLengthNbBytes()) {
            byte octet = stream.get();
            if (IS_DEBUG) {
                LOG.debug(I18n.msg(I18n.MSG_01002_CURRENT_BYTE, Asn1StringUtils.dumpByte(octet)));
            }
            tlv.incLengthBytesRead();
            length = (length << 8) | (octet & 0x00FF);
            if (!stream.hasRemaining()) {
                tlv.setLength(length);
                if (tlv.getLengthBytesRead() < tlv.getLengthNbBytes()) {
                    container.setState(TLVStateEnum.LENGTH_STATE_PENDING);
                    return END;
                } else {
                    container.setState(TLVStateEnum.LENGTH_STATE_END);
                    return MORE;
                }
            }
        }
        tlv.setLength(length);
        container.setState(TLVStateEnum.LENGTH_STATE_END);
        return MORE;
    } else {
        return END;
    }
}
Also used : TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 25 with Asn1Container

use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.

the class Asn1Decoder method dumpTLVTree.

/**
 * Dump the current TLV tree
 *
 * @param container The container
 */
private void dumpTLVTree(Asn1Container container) {
    StringBuilder sb = new StringBuilder();
    TLV current = container.getCurrentTLV();
    sb.append("TLV").append(Asn1StringUtils.dumpByte(current.getTag())).append("(").append(current.getExpectedLength()).append(")");
    current = current.getParent();
    while (current != null) {
        sb.append("-TLV").append(Asn1StringUtils.dumpByte(current.getTag())).append("(").append(current.getExpectedLength()).append(")");
        current = current.getParent();
    }
    if (IS_DEBUG) {
        LOG.debug(I18n.msg(I18n.MSG_01001_TLV_TREE, sb.toString()));
    }
}
Also used : TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Aggregations

DecoderException (org.apache.directory.api.asn1.DecoderException)40 Asn1Decoder (org.apache.directory.api.asn1.ber.Asn1Decoder)39 ByteBuffer (java.nio.ByteBuffer)38 Test (org.junit.Test)38 Asn1Container (org.apache.directory.api.asn1.ber.Asn1Container)36 LdapMessageContainer (org.apache.directory.api.ldap.codec.api.LdapMessageContainer)30 AbstractCodecServiceTest (org.apache.directory.api.ldap.codec.osgi.AbstractCodecServiceTest)29 TLV (org.apache.directory.api.asn1.ber.tlv.TLV)10 EncoderException (org.apache.directory.api.asn1.EncoderException)6 CancelContainer (org.apache.directory.api.ldap.extras.extended.ads_impl.cancel.CancelContainer)5 CancelDecoder (org.apache.directory.api.ldap.extras.extended.ads_impl.cancel.CancelDecoder)5 Message (org.apache.directory.api.ldap.model.message.Message)4 ResponseCarryingException (org.apache.directory.api.ldap.codec.api.ResponseCarryingException)3 AddResponseImpl (org.apache.directory.api.ldap.model.message.AddResponseImpl)3 BerValue (org.apache.directory.api.asn1.ber.tlv.BerValue)2 BindRequestDecorator (org.apache.directory.api.ldap.codec.decorators.BindRequestDecorator)2 BindRequest (org.apache.directory.api.ldap.model.message.BindRequest)2 CheckNotNullLength (org.apache.directory.api.asn1.actions.CheckNotNullLength)1 MessageDecorator (org.apache.directory.api.ldap.codec.api.MessageDecorator)1 AndFilter (org.apache.directory.api.ldap.codec.search.AndFilter)1