You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2005/09/21 09:20:42 UTC
svn commit: r290642 -
/directory/asn1/trunk/ber-new/src/java/main/org/apache/asn1new/ber/Asn1Decoder.java
Author: elecharny
Date: Wed Sep 21 00:20:37 2005
New Revision: 290642
URL: http://svn.apache.org/viewcvs?rev=290642&view=rev
Log:
Fixed a bug in the decoder that leads to badly decode some PDU. The code has been fully rechecked, just in case.
Modified:
directory/asn1/trunk/ber-new/src/java/main/org/apache/asn1new/ber/Asn1Decoder.java
Modified: directory/asn1/trunk/ber-new/src/java/main/org/apache/asn1new/ber/Asn1Decoder.java
URL: http://svn.apache.org/viewcvs/directory/asn1/trunk/ber-new/src/java/main/org/apache/asn1new/ber/Asn1Decoder.java?rev=290642&r1=290641&r2=290642&view=diff
==============================================================================
--- directory/asn1/trunk/ber-new/src/java/main/org/apache/asn1new/ber/Asn1Decoder.java (original)
+++ directory/asn1/trunk/ber-new/src/java/main/org/apache/asn1new/ber/Asn1Decoder.java Wed Sep 21 00:20:37 2005
@@ -98,69 +98,66 @@
private boolean treatTagStartState( ByteBuffer stream, IAsn1Container container )
throws DecoderException
{
-
if ( stream.hasRemaining() )
{
-
byte octet = stream.get();
-
+
TLV tlv = new TLV();
Tag tag = tlv.getTag();
-
- tag.setSize( 1 );
+
tag.setPrimitive( ( octet & Tag.CONSTRUCTED_FLAG ) == 0 );
tag.setTypeClass( Tag.TYPE_CLASS[( octet & Tag.TYPE_CLASS_MASK ) >>> 6] );
-
+
int value = octet & Tag.SHORT_MASK;
-
+
if ( value == Tag.SHORT_MASK )
{
-
+ // It's a tag wich value is above 31
// we have to check the typeClass. UNIVERSAL class is not
// allowed with this value.
if ( tag.isUniversal() )
{
throw new DecoderException( "Universal tag 31 is reserved" );
}
-
+
// we will have more than one byte to encode the value
// The tag is encoded on [2 - 6 bytes], its value
- // is container in the 7 lower bits of the bytes following
+ // is contained in the 7 lower bits of the bytes following
// the first byte.
container.setState( TLVStateEnum.TAG_STATE_PENDING );
tag.setId( 0 );
tag.addByte( octet );
+ tag.setSize( 0 );
}
else
{
// It's a tag wich value is below 30 (31 is not allowed
- // as it signals a multi-bytes value. Everything is done.
-
+ // as it signals a multi-bytes value). The tag's length is 1 byte
+ tag.setSize( 1 );
+
// We have to check for reserved tags if typeClass is UNIVERSAL
if ( tag.isUniversal() )
{
-
if ( ( value == UniversalTag.RESERVED_14 ) || ( value == UniversalTag.RESERVED_15 ) )
{
throw new DecoderException( "Universal tag " + value + " is reserved" );
}
}
-
+
tag.setId( value );
tag.addByte( octet );
-
+
// The tag has been completed, we have to decode the Length
container.setState( TLVStateEnum.TAG_STATE_END );
}
-
+
// Store the current TLV in the container.
container.setCurrentTLV( tlv );
-
+
return MORE;
}
else
{
-
// The stream has been exhausted
return END;
}
@@ -182,40 +179,35 @@
private boolean treatTagPendingState( ByteBuffer stream, IAsn1Container container )
throws DecoderException
{
-
if ( stream.hasRemaining() )
{
-
Tag tag = container.getCurrentTLV().getTag();
byte octet = stream.get();
-
+
if ( tag.getSize() >= Tag.MAX_TAG_BYTES )
{
container.setState( TLVStateEnum.TAG_STATE_OVERFLOW );
log.error( "Tag label Overflow" );
throw new DecoderException( "Tag label overflow" );
}
-
+
byte val = ( byte ) ( octet & Tag.LONG_MASK );
-
+
tag.setId( ( tag.getId() << 7 ) | val );
tag.incTagSize();
-
+
if ( val == octet )
{
-
// The Tag is completed, so let's decode the Length
container.setState( TLVStateEnum.LENGTH_STATE_START );
}
-
+
return MORE;
}
else
{
-
return END;
}
-
}
/**
@@ -227,25 +219,26 @@
StringBuffer sb = new StringBuffer();
TLV current = container.getCurrentTLV();
- sb.append("TLV").
- append(StringUtils.dumpByte(current.getTag().getTagBytes()[0])).
- append("(").
- append(current.getExpectedLength()).
- append(")");
+ sb.append( "TLV" ).
+ append( StringUtils.dumpByte( current.getTag().getTagBytes()[0] ) ).
+ append( "(" ).
+ append( current.getExpectedLength() ).
+ append( ")" );
current = current.getParent();
while (current != null)
{
- sb.append("-TLV").
- append(StringUtils.dumpByte(current.getTag().getTagBytes()[0])).
- append("(").
- append(current.getExpectedLength()).
- append(")");
+ sb.append( "-TLV" ).
+ append( StringUtils.dumpByte( current.getTag().getTagBytes()[0] ) ).
+ append( "(" ).
+ append( current.getExpectedLength() ).
+ append( ")" );
+
current = current.getParent();
}
- log.debug("TLV Tree : " + sb.toString());
+ log.debug( "TLV Tree : " + sb.toString() );
}
/**
@@ -254,11 +247,11 @@
*/
private boolean isTLVDecoded( IAsn1Container container )
{
- TLV current = container.getCurrentTLV();
+ TLV currentTLV = container.getCurrentTLV();
- TLV parent = current.getParent();
+ TLV parent = currentTLV.getParent();
- while (parent != null)
+ while ( parent != null )
{
if (parent.getExpectedLength() != 0)
{
@@ -268,15 +261,15 @@
parent = parent.getParent();
}
- Value value = current.getValue();
+ Value value = currentTLV.getValue();
- if ( (value != null) && (value.getData() != null) )
+ if ( ( value != null ) && ( value.getData() != null ) )
{
- return (current.getExpectedLength() == value.getData().length);
+ return ( currentTLV.getExpectedLength() == value.getData().length );
}
else
{
- return current.getExpectedLength() == 0;
+ return currentTLV.getExpectedLength() == 0;
}
}
@@ -293,18 +286,20 @@
private void treatTagEndState( IAsn1Container container )
throws DecoderException
{
+ TLV currentTlv = container.getCurrentTLV();
if ( DEBUG )
{
- Tag tag = container.getCurrentTLV().getTag();
+ Tag tag = currentTlv.getTag();
log.debug( tag.toString() + " has been decoded" );
}
- // Create a link between the current TLV with its parent
- container.getCurrentTLV().setParent(container.getParentTLV());
+ // Create a link between the current TLV with its parent, if any.
+ currentTlv.setParent( container.getParentTLV() );
// After having decoded a tag, we have to execute the action
// which controls if this tag is allowed and well formed.
+ // TODO : this is totally useless.
container.getGrammar().executeAction( container );
// Switch to the next state, which is the Length decoding
@@ -327,39 +322,37 @@
private boolean treatLengthStartState( ByteBuffer stream, IAsn1Container container )
throws DecoderException
{
-
if ( stream.hasRemaining() )
{
-
byte octet = stream.get();
-
+
Length length = container.getCurrentTLV().getLength();
-
+
if ( ( octet & Length.LENGTH_LONG_FORM ) == 0 )
{
-
+
// We don't have a long form. The Length of the Value part is
// given by this byte.
length.setLength( octet );
length.setExpectedLength( 0 );
length.setCurrentLength( 0 );
length.setSize( 1 );
-
+
container.setState( TLVStateEnum.LENGTH_STATE_END );
}
else if ( ( octet & Length.LENGTH_EXTENSION_RESERVED ) !=
Length.LENGTH_EXTENSION_RESERVED )
{
-
+
int expectedLength = octet & Length.SHORT_MASK;
-
+
if ( expectedLength > 4 )
{
log.error( "Overflow : can't have more than 4 bytes long length" );
throw new DecoderException(
"Overflow : can't have more than 4 bytes long length" );
}
-
+
length.setExpectedLength( expectedLength );
length.setCurrentLength( 0 );
length.setLength( 0 );
@@ -376,7 +369,6 @@
}
else
{
-
return END;
}
}
@@ -397,34 +389,31 @@
private boolean treatLengthPendingState( ByteBuffer stream, IAsn1Container container )
throws DecoderException
{
-
- if ( stream.hasRemaining() )
+ if (stream.hasRemaining() )
{
-
Length length = container.getCurrentTLV().getLength();
-
+
while ( length.getCurrentLength() < length.getExpectedLength() )
{
-
+
byte octet = stream.get();
-
+
if ( DEBUG )
{
log.debug( " current byte : " + StringUtils.dumpByte( octet ) );
}
-
+
length.incCurrentLength();
length.incSize();
length.setLength( ( length.getLength() << 8 ) | (octet & 0x00FF));
}
-
+
container.setState( TLVStateEnum.LENGTH_STATE_END );
-
+
return MORE;
}
else
{
-
return END;
}
}
@@ -471,7 +460,7 @@
throws DecoderException
{
TLV tlv = container.getCurrentTLV();
- Length length = tlv.getLength();
+ int length = tlv.getLength().getLength();
// We will check the length here. What we must control is
// that the enclosing constructed TLV expected length is not
@@ -480,19 +469,19 @@
if ( DEBUG )
{
- log.debug(getParentLength(parentTLV));
+ log.debug( getParentLength( parentTLV ) );
}
- if (parentTLV == null)
+ 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.getLength());
- container.setParentTLV(tlv);
+ tlv.setExpectedLength( length );
+ container.setParentTLV( tlv );
if ( DEBUG )
{
- log.debug("Root TLV[" + tlv.getLength().getLength() + "]");
+ log.debug( "Root TLV[" + length + "]" );
}
}
else
@@ -502,46 +491,46 @@
int expectedLength = parentTLV.getExpectedLength();
int currentLength = tlv.getSize();
- if (expectedLength < currentLength)
+ if ( expectedLength < currentLength )
{
// The expected length is lower than the Value length of the
// current TLV. This is an error...
- log.error("tlv[" + expectedLength + ", " + currentLength + "]");
- throw new DecoderException("The current Value length is above the expected length");
+ log.error( "tlv[" + expectedLength + ", " + currentLength + "]" );
+ throw new DecoderException( "The current Value length is above the expected length" );
}
- if (expectedLength == currentLength)
+ if ( expectedLength == currentLength )
{
- parentTLV.setExpectedLength(0);
-
// deal with the particular case where expected length equal
// the current length, which means that the parentTLV has been
// completed.
- // We also have to check that the current TLV is a constructed
- // one.
+ // The parent length must be reset.
+ parentTLV.setExpectedLength( 0 );
+ tlv.setExpectedLength( length );
+
+ // Check the current length, and also check that the current TLV
+ // is a constructed one.
// In this case, we have to switch from this parent TLV
// to the parent's parent TLV.
- if (tlv.getTag().isConstructed())
+ if ( ( length != 0 ) && ( tlv.getTag().isConstructed() ) )
{
// It's a constructed TLV. We will set it's parent to the
// parentTLV, and it will become the new parent TLV, after
- // having set the new expected length.
- tlv.setParent(parentTLV);
- tlv.setExpectedLength(tlv.getLength().getLength());
- container.setParentTLV(tlv);
+ // having set the new expected length
+ tlv.setParent( parentTLV ) ;
+ container.setParentTLV( tlv );
}
else
{
- tlv.setExpectedLength(tlv.getLength().getLength());
- // It's over, the parent TLV has been completed.
- // Go back to the parent's parent TLV until we find
- // a tlv which is not complete.
- while (parentTLV != null)
+ // We have to unstack the parentTLV until we
+ // find one which length is not null. It will
+ // become the container parentTLV.
+ while ( parentTLV != null )
{
if ( parentTLV.getExpectedLength() != 0 )
{
- // ok, we have an incomplete parent. we will
- // stop the recursion right here
+ // Ok, we have an incomplete parent. we will
+ // stop the recursion rigth here
break;
}
else
@@ -549,41 +538,41 @@
parentTLV = parentTLV.getParent();
}
}
-
- container.setParentTLV(parentTLV);
+
+ // The parent might be null.
+ container.setParentTLV( parentTLV ) ;
}
}
else
{
// Renew the expected Length.
- parentTLV.setExpectedLength(expectedLength - currentLength);
- tlv.setExpectedLength(tlv.getLength().getLength());
+ parentTLV.setExpectedLength( expectedLength - currentLength) ;
+ tlv.setExpectedLength( length );
- if (tlv.getTag().isConstructed())
+ if ( tlv.getTag().isConstructed() )
{
- // We have a constructed tag, so we must switch the parentTLV
- tlv.setParent(parentTLV);
- tlv.setExpectedLength(tlv.getLength().getLength());
- container.setParentTLV(tlv);
+ // We have a constructed tag, so we must change the
+ // container parentTLV. The current container parentTLV
+ // will be store in the current TLV.
+ tlv.setParent( parentTLV );
+ tlv.setExpectedLength( length );
+ container.setParentTLV( tlv );
}
}
-
}
if ( DEBUG )
{
- log.debug( length.toString() + " has been decoded" );
+ log.debug( tlv.getLength().toString() + " has been decoded" );
}
- if ( length.getLength() == 0 )
+ 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 );
}
@@ -606,13 +595,13 @@
private boolean treatValueStartState( ByteBuffer stream, IAsn1Container container )
throws DecoderException
{
-
TLV currentTlv = container.getCurrentTLV();
+ Value value = currentTlv.getValue();
if ( currentTlv.getTag().isConstructed() )
{
container.setState( TLVStateEnum.TLV_STATE_DONE );
-
+
return MORE;
}
else
@@ -620,21 +609,20 @@
int length = currentTlv.getLength().getLength();
int nbBytes = stream.remaining();
+ value.init( length );
if ( nbBytes < length )
{
- currentTlv.getValue().init( length );
- currentTlv.getValue().setData( stream );
+ value.setData( stream );
container.setState( TLVStateEnum.VALUE_STATE_PENDING );
-
+
return END;
}
else
{
- currentTlv.getValue().init( length );
- stream.get( currentTlv.getValue().getData(), 0, length );
+ stream.get( value.getData(), 0, length );
container.setState( TLVStateEnum.TLV_STATE_DONE );
-
+
return MORE;
}
}
@@ -658,16 +646,17 @@
{
TLV currentTlv = container.getCurrentTLV();
+ Value value = currentTlv.getValue();
int length = currentTlv.getLength().getLength();
- int currentLength = currentTlv.getValue().getCurrentLength();
+ int currentLength = value.getCurrentLength();
int nbBytes = stream.remaining();
if ( ( currentLength + nbBytes ) < length )
{
- currentTlv.getValue().addData( stream );
+ value.addData( stream );
container.setState( TLVStateEnum.VALUE_STATE_PENDING );
-
+
return END;
}
else
@@ -676,9 +665,9 @@
int remaining = length - currentLength;
byte[] data = new byte[remaining];
stream.get( data, 0, remaining );
- currentTlv.getValue().addData( data );
+ value.addData( data );
container.setState( TLVStateEnum.TLV_STATE_DONE );
-
+
return MORE;
}
}
@@ -733,10 +722,8 @@
*/
private String stateToString( int state )
{
-
switch ( state )
{
-
case TLVStateEnum.TAG_STATE_START :
return "TAG_STATE_START";
@@ -784,7 +771,7 @@
*
* @throws DecoderException Thrown if anything went wrong!
*/
- public void decode( ByteBuffer stream, IAsn1Container container ) throws org.apache.asn1.codec.DecoderException
+ public void decode( ByteBuffer stream, IAsn1Container container ) throws DecoderException
{
/* We have to deal with the current state. This is an
@@ -796,7 +783,7 @@
* all information to track back this case, and punish the guilty !
*/
- boolean hasRemaining = stream.hasRemaining();
+ // boolean hasRemaining = stream.hasRemaining();
if ( DEBUG )
{
@@ -805,6 +792,8 @@
log.debug( ">>>------------------------------------------" );
}
+ boolean hasRemaining = stream.hasRemaining();
+
while ( hasRemaining )
{
@@ -826,7 +815,6 @@
switch ( container.getState() )
{
-
case TLVStateEnum.TAG_STATE_START :
hasRemaining = treatTagStartState( stream, container );
@@ -872,7 +860,7 @@
break;
case TLVStateEnum.VALUE_STATE_END :
- hasRemaining = stream.hasRemaining();
+ hasRemaining = stream.hasRemaining();
// Nothing to do. We will never reach this state
break;
@@ -890,25 +878,22 @@
log.warn("The PDU has been fully decoded but there are still bytes in the buffer.");
}
- hasRemaining = false;
+ if ( DEBUG )
+ {
+ log.debug( "<<<------------------------------------------" );
+ log.debug( "<-- Stop decoding : " + container.getCurrentTLV().toString() );
+ log.debug( "<<<==========================================" );
+ }
- break;
+ return;
}
}
if ( DEBUG )
{
log.debug( "<<<------------------------------------------" );
-
- if ( container.getState() == TLVStateEnum.PDU_DECODED )
- {
- log.debug( "<-- Stop decoding : " + container.getCurrentTLV().toString() );
- }
- else
- {
- log.debug( "<-- End decoding : " + container.getCurrentTLV().toString() );
- }
-
+ log.debug( " no more byte to decode in the stream");
+ log.debug( "<-- End decoding : " + container.getCurrentTLV().toString() );
log.debug( "<<<==========================================" );
}