1   /*
2    *   Copyright 2004-2005 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.asn1.ber ;
18  
19  
20  import java.nio.ByteBuffer ;
21  import java.util.ArrayList ;
22  
23  import org.apache.commons.lang.ArrayUtils ;
24  import org.apache.commons.lang.RandomStringUtils ;
25  
26  import org.apache.asn1.codec.stateful.StatefulDecoder ;
27  import org.apache.asn1.codec.stateful.DecoderCallback;
28  import org.apache.asn1.codec.stateful.DecoderMonitorAdapter;
29  import org.apache.asn1.codec.stateful.*;
30  import org.apache.asn1.ber.AbstractDecoderTestCase;
31  import org.apache.asn1.ber.BERDecoderMonitor;
32  
33  
34  /***
35   * Tests the decoder using various complext TLV decoding scenarios and performs
36   * round trip encode - decode functionality.
37   *
38   * @author <a href="mailto:dev@directory.apache.org">
39   * Apache Directory Project</a>
40   * @version $Rev: 157644 $
41   */
42  public class BERDecoderTest extends AbstractDecoderTestCase
43  {
44      private static final ByteBuffer EMPTY_BUFFER =
45          ByteBuffer.wrap( ArrayUtils.EMPTY_BYTE_ARRAY ) ;
46  
47  
48      public BERDecoderTest()
49      {
50          super( BERDecoderTest.class.getName() ) ;
51      }
52  
53  
54      public void testBasisCases() throws Exception
55      {
56          decoder.setDecoderMonitor( new DecoderMonitorAdapter() ) ;
57          decoder.decode( null ) ;
58          decoder.decode( EMPTY_BUFFER ) ;
59      }
60  
61  
62      public void testPrimitives() throws Exception
63      {
64          Tuple decoded = null ;
65          Tuple t = new Tuple( 45, 0, true, TypeClass.APPLICATION ) ;
66          assertTrue( decode( t, EMPTY_BUFFER ).equals( t ) ) ;
67  
68          t = new Tuple( 45, "Hello world!".length(), true,
69                  TypeClass.APPLICATION ) ;
70          decoded = decode( t, ByteBuffer.wrap( "Hello world!".getBytes() ) ) ;
71          assertTrue( decoded.equals( t ) ) ;
72          assertEquals( "Hello world!", toString( decoded.getLastValueChunk() ) ) ;
73  
74          String mesg = RandomStringUtils.randomAlphanumeric(1000) ;
75          t = new Tuple( 1234233, mesg.length(), true, TypeClass.APPLICATION ) ;
76          decoded = decode( t, ByteBuffer.wrap( mesg.getBytes() ) ) ;
77          assertTrue( decoded.equals( t ) ) ;
78          assertEquals( mesg, toString( decoded.getLastValueChunk() ) ) ;
79      }
80  
81  
82      String toString(ByteBuffer buf)
83      {
84          buf = buf.slice() ;
85          byte[] bites = new byte[buf.remaining()] ;
86          buf.get( bites ) ;
87          return new String( bites ) ;
88      }
89  
90  
91      public void testConstructedIndefinite() throws Exception
92      {
93          Tuple top = new Tuple( 1, TypeClass.APPLICATION ) ;
94          Tuple t0 = new Tuple( 2, "Hello".length(),
95                  true, TypeClass.APPLICATION ) ;
96          Tuple t1 = new Tuple( 3, "World".length(),
97                  true, TypeClass.APPLICATION ) ;
98          Tuple terminator = new Tuple( 0, 0, true, TypeClass.UNIVERSAL ) ;
99          assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
100 
101         Tuple decoded = decode( t0, ByteBuffer.wrap( "Hello".getBytes() ) ) ;
102         assertTrue( decoded.equals( t0 ) ) ;
103         assertEquals( "Hello", toString( decoded.getLastValueChunk() ) ) ;
104 
105         decoded = decode( t1, ByteBuffer.wrap( "World".getBytes() ) ) ;
106         assertTrue( decoded.equals( t1 ) ) ;
107         assertEquals( "World", toString( decoded.getLastValueChunk() ) ) ;
108 
109         decoded = decode( terminator, EMPTY_BUFFER ) ;
110         assertTrue( decoded.equals( top ) ) ;
111     }
112 
113 
114     public void testConstructedLongLengthForm() throws Exception
115     {
116         String str0 = RandomStringUtils.randomAlphanumeric(128) ;
117         Tuple t0 = new Tuple( 2, 128, true, TypeClass.APPLICATION ) ;
118         String str1 = RandomStringUtils.randomAlphanumeric(128) ;
119         Tuple t1 = new Tuple( 3, 128, true, TypeClass.APPLICATION ) ;
120         Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
121         assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
122 
123         Tuple decoded = decode( t0, ByteBuffer.wrap( str0.getBytes() ) ) ;
124         assertTrue( decoded.equals( t0 ) ) ;
125         assertEquals( str0, toString( decoded.getLastValueChunk() ) ) ;
126 
127         // automatically set to top because after t1 is delivered top is
128         decoded = decode( t1, ByteBuffer.wrap( str1.getBytes() ) ) ;
129         assertTrue( decoded.equals( top ) ) ;
130     }
131 
132 
133     public void testConstructedShortLengthForm() throws Exception
134     {
135         Tuple t0 = new Tuple( 2, "Hello".length(), true,
136                 TypeClass.APPLICATION ) ;
137         Tuple t1 = new Tuple( 3, "World".length(), true,
138                 TypeClass.APPLICATION ) ;
139         Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
140         assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
141 
142         Tuple decoded = decode( t0, ByteBuffer.wrap( "Hello".getBytes() ) ) ;
143         assertTrue( decoded.equals( t0 ) ) ;
144         assertEquals( "Hello", toString( decoded.getLastValueChunk() ) ) ;
145 
146         // automatically set to top because after t1 is delivered top is
147         decoded = decode( t1, ByteBuffer.wrap( "World".getBytes() ) ) ;
148         assertTrue( decoded.equals( top ) ) ;
149     }
150 
151 
152     public void testFragmentedValue() throws Exception
153     {
154         String str0 = RandomStringUtils.randomAlphanumeric(20) ;
155         Tuple t0 = new Tuple( 2, str0.length(), true, TypeClass.APPLICATION ) ;
156         String str1 = RandomStringUtils.randomAlphanumeric(20) ;
157         Tuple t1 = new Tuple( 3, str1.length(), true, TypeClass.APPLICATION ) ;
158         Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
159         assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
160 
161         ArrayList list = new ArrayList() ;
162         list.add( ByteBuffer.wrap( str0.getBytes() ) ) ;
163         ByteBuffer all = t0.toEncodedBuffer( list ) ;
164         ByteBuffer[] fragments = fragment( all, 10 ) ;
165         Tuple decoded = null ;
166 
167         for ( int ii = 0; ii < fragments.length; ii++ )
168         {
169             decoded = decode( fragments[ii] ) ;
170         }
171 
172         assertTrue( decoded.equals( t0 ) ) ;
173         assertEquals( str0, toString( buf ) ) ;
174 
175         // automatically set to top because after t1 is delivered top is
176         decoded = decode( t1, ByteBuffer.wrap( str1.getBytes() ) ) ;
177         assertTrue( decoded.equals( top ) ) ;
178     }
179 
180 
181     public void testDecodeOccurred()
182     {
183         try
184         {
185             decoder.decodeOccurred( null, null ) ;
186             fail( "should never get here due to exception being thrown" ) ;
187         }
188         catch ( IllegalArgumentException e )
189         {
190             assertNotNull( e ) ;
191         }
192     }
193 
194 
195     public void testFireTagDecoded() throws Exception
196     {
197         decoder.setDecoderMonitor( new BERMonitor() ) ;
198         String str0 = RandomStringUtils.randomAlphanumeric(20) ;
199         Tuple t0 = new Tuple( 2, str0.length() ) ;
200         String str1 = RandomStringUtils.randomAlphanumeric(20) ;
201         Tuple t1 = new Tuple( 3, str1.length() ) ;
202         Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
203         Tuple decoded = decode( t0, ByteBuffer.wrap( str0.getBytes() ) ) ;
204         assertTrue( decoded.equals( t0 ) ) ;
205 
206         // automatically set to top because after t1 is delivered top is
207         decoded = decode( t1, ByteBuffer.wrap( str1.getBytes() ) ) ;
208 
209         assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
210 
211         decoder.setDecoderMonitor(null) ;
212         decoded = decode( t0, ByteBuffer.wrap( str0.getBytes() ) ) ;
213         assertTrue( decoded.equals( t0 ) ) ;
214 
215         tlvList.clear() ;
216         decoder.setDecoderMonitor(null) ;
217         decoder.setCallback(null) ;
218         decoded = decode( t0, ByteBuffer.wrap( str0.getBytes() ) ) ;
219         assertTrue(tlvList.isEmpty()) ;
220     }
221 
222 
223     public void testFireTagDecoded2() throws Exception
224     {
225         decoder.setDecoderMonitor( null ) ;
226         String str0 = RandomStringUtils.randomAlphanumeric(20) ;
227         Tuple t0 = new Tuple( 2, str0.length() ) ;
228         String str1 = RandomStringUtils.randomAlphanumeric(20) ;
229         Tuple t1 = new Tuple( 3, str1.length() ) ;
230         Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
231         Tuple decoded = decode( t0, ByteBuffer.wrap( str0.getBytes() ) ) ;
232         assertTrue( decoded.equals( t0 ) ) ;
233 
234         // automatically set to top because after t1 is delivered top is
235         decoded = decode( t1, ByteBuffer.wrap( str1.getBytes() ) ) ;
236         assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
237     }
238 
239 
240     public void testFireTagDecoded3() throws Exception
241     {
242         decoder.setDecoderMonitor( new BERMonitor() ) ;
243         decoder.setCallback( null ) ;
244         String str0 = RandomStringUtils.randomAlphanumeric(20) ;
245         Tuple t0 = new Tuple( 2, str0.length() ) ;
246         String str1 = RandomStringUtils.randomAlphanumeric(20) ;
247         Tuple t1 = new Tuple( 3, str1.length() ) ;
248         Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
249         decode( t0, ByteBuffer.wrap( str0.getBytes() ) ) ;
250 
251         // automatically set to top because after t1 is delivered top is
252         decode( t1, ByteBuffer.wrap( str1.getBytes() ) ) ;
253         assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
254     }
255 
256 
257     public void testFireTagDecoded4() throws Exception
258     {
259         decoder.setDecoderMonitor( null ) ;
260         decoder.setCallback( null ) ;
261         String str0 = RandomStringUtils.randomAlphanumeric(20) ;
262         Tuple t0 = new Tuple( 2, str0.length() ) ;
263         String str1 = RandomStringUtils.randomAlphanumeric(20) ;
264         Tuple t1 = new Tuple( 3, str1.length() ) ;
265         Tuple top = new Tuple( 1, t0.size() + t1.size() ) ;
266         decode( t0, ByteBuffer.wrap( str0.getBytes() ) );
267 
268         // automatically set to top because after t1 is delivered top is
269         decode( t1, ByteBuffer.wrap( str1.getBytes() ) ) ;
270         assertTrue( decode( top, EMPTY_BUFFER ).equals( top ) ) ;
271     }
272 
273 
274     class BERMonitor implements BERDecoderMonitor
275     {
276         public void callbackOccured(StatefulDecoder decoder,
277                 DecoderCallback cb, Object decoded) { }
278 
279         public void error(StatefulDecoder decoder, Exception exception) { }
280 
281         public void callbackSet(StatefulDecoder decoder, DecoderCallback oldcb,
282                 DecoderCallback newcb) { }
283 
284         public void fatalError(StatefulDecoder decoder, Exception exception){}
285 
286         public void lengthDecoded( Tuple tlv ) { }
287 
288         public void tagDecoded( Tuple tlv ) { }
289 
290         public void warning( StatefulDecoder decoder, Exception exception ) { }
291     }
292 }