directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From trus...@apache.org
Subject svn commit: r354703 - in /directory/network/trunk/src/java/org/apache/mina: common/ByteBuffer.java filter/codec/serialization/ObjectSerializationDecoder.java
Date Wed, 07 Dec 2005 04:29:32 GMT
Author: trustin
Date: Tue Dec  6 20:29:25 2005
New Revision: 354703

URL: http://svn.apache.org/viewcvs?rev=354703&view=rev
Log:
Resolved issue: DIRMINA-140 (ByteBuffer.prefixedDataAvailable())
* Added ByteBuffer.prefixedDataAvailable()
* Simplified ObjectSerilizationDecoder to use ByteBuffer.prefixedDataAvailable()
* All prefixed data type getter/setter throw BufferUnderflowException before reading the partial
content thanks to prefixedDataAvailable()

Modified:
    directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java
    directory/network/trunk/src/java/org/apache/mina/filter/codec/serialization/ObjectSerializationDecoder.java

Modified: directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java?rev=354703&r1=354702&r2=354703&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java Tue Dec  6 20:29:25
2005
@@ -1287,7 +1287,12 @@
      */
     public String getPrefixedString( int prefixLength, CharsetDecoder decoder ) throws CharacterCodingException
     {
-        int fieldSize;
+        if( !prefixedDataAvailable( prefixLength ) )
+        {
+            throw new BufferUnderflowException();
+        }
+
+        int fieldSize = 0;
         
         switch( prefixLength )
         {
@@ -1300,13 +1305,6 @@
         case 4:
             fieldSize = getInt();
             break;
-        default:
-            throw new IllegalArgumentException( "prefixLength: " + prefixLength );
-        }
-
-        if( fieldSize < 0 )
-        {
-            throw new BufferDataException( "Invalid fieldSize: " + fieldSize );
         }
         
         if( fieldSize == 0 )
@@ -1546,11 +1544,12 @@
      */
     public Object getObject( final ClassLoader classLoader ) throws ClassNotFoundException
     {
-        int length = getInt();
-        if( length > remaining() )
+        if( !prefixedDataAvailable( 4 ) )
         {
             throw new BufferUnderflowException();
         }
+
+        int length = getInt();
         if( length <= 4 )
         {
             throw new BufferDataException( "Object length should be greater than 4: " + length
);
@@ -1612,6 +1611,68 @@
         putInt( newPos - oldPos - 4 );
         position( newPos );
         return this;
+    }
+    
+    /**
+     * Returns <tt>true</tt> if this buffer contains a data which has a data
+     * length as a prefix and the buffer has remaining data as enough as
+     * specified in the data length field.  This method is identical with
+     * <tt>prefixedDataAvailable( prefixLength, Integer.MAX_VALUE )</tt>.
+     * Please not that using this method can allow DoS (Denial of Service)
+     * attack in case the remote peer sends too big data length value.
+     * It is recommended to use {@link #prefixedDataAvailable(int, int)}
+     * instead. 
+     * 
+     * @param prefixLength the length of the prefix field (1, 2, or 4)
+     * 
+     * @throws IllegalArgumentException if prefixLength is wrong
+     * @throws BufferDataException if data length is negative
+     */
+    public boolean prefixedDataAvailable( int prefixLength )
+    {
+        return prefixedDataAvailable( prefixLength, Integer.MAX_VALUE );
+    }
+    
+    /**
+     * Returns <tt>true</tt> if this buffer contains a data which has a data
+     * length as a prefix and the buffer has remaining data as enough as
+     * specified in the data length field.
+     * 
+     * @param prefixLength the length of the prefix field (1, 2, or 4)
+     * @param maxDataLength the allowed maximum of the read data length
+     * 
+     * @throws IllegalArgumentException if prefixLength is wrong
+     * @throws BufferDataException if data length is negative or greater then <tt>maxDataLength</tt>
+     */
+    public boolean prefixedDataAvailable( int prefixLength, int maxDataLength )
+    {
+        if( remaining() < prefixLength )
+        {
+            return false;
+        }
+
+        int dataLength;
+        switch( prefixLength )
+        {
+        case 1:
+            dataLength = getUnsigned( position() );
+            break;
+        case 2:
+            dataLength = getUnsignedShort( position() );
+            break;
+        case 4:
+            dataLength = getInt( position() );
+            break;
+        default:
+            throw new IllegalArgumentException( "prefixLength: " + prefixLength );
+        }
+        
+        if( dataLength < 0 || dataLength > maxDataLength )
+        {
+            throw new BufferDataException( "dataLength: " + dataLength );
+        }
+        
+        return remaining() - prefixLength >= dataLength;
     }
 
     //////////////////////////

Modified: directory/network/trunk/src/java/org/apache/mina/filter/codec/serialization/ObjectSerializationDecoder.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/filter/codec/serialization/ObjectSerializationDecoder.java?rev=354703&r1=354702&r2=354703&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/filter/codec/serialization/ObjectSerializationDecoder.java
(original)
+++ directory/network/trunk/src/java/org/apache/mina/filter/codec/serialization/ObjectSerializationDecoder.java
Tue Dec  6 20:29:25 2005
@@ -89,30 +89,12 @@
 
     protected boolean doDecode( IoSession session, ByteBuffer in, ProtocolDecoderOutput out
) throws Exception
     {
-        if( in.remaining() < 4 )
+        if( !in.prefixedDataAvailable( 4, maxObjectSize ) )
         {
             return false;
         }
-        
-        int baseIndex = in.position();
-        int objectSize = in.getInt( baseIndex );
-        if( objectSize <= 4 )
-        {
-            throw new BufferDataException( "Invalid object length: " + objectSize );
-        }
-        if( objectSize > maxObjectSize )
-        {
-            throw new BufferDataException( "The object to decode is too big: " + objectSize
+ " (> " + maxObjectSize + ')' );
-        }
-        
-        if( objectSize + 4 > in.remaining() )
-        {
-            return false;
-        }
-        else
-        {
-            out.write( in.getObject( classLoader ) );
-            return true;
-        }
+
+        out.write( in.getObject( classLoader ) );
+        return true;
     }
 }



Mime
View raw message