1   /*
2    *   Copyright 2004 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 org.apache.commons.lang.ArrayUtils ;
21  import org.apache.asn1.ber.primitives.UniversalTag;
22  import org.apache.asn1.ber.primitives.UniversalTag;
23  import org.apache.asn1.ber.Tag;
24  
25  import junit.framework.TestCase ;
26  
27  import java.nio.BufferOverflowException;
28  
29  
30  /***
31   * Tests the BER utility functions.
32   *
33   * @author <a href="mailto:dev@directory.apache.org">
34   * Apache Directory Project</a>
35   * @version $Rev: 157644 $
36   */
37  public class TagTest extends TestCase
38  {
39      private static final int BIT_0 = 0x01 ;
40      private static final int BIT_1 = 0x02 ;
41      private static final int BIT_2 = 0x04 ;
42      private static final int BIT_3 = 0x08 ;
43      private static final int BIT_4 = 0x10 ;
44      private static final int BIT_5 = 0x20 ;
45      private static final int BIT_6 = 0x40 ;
46      private static final int BIT_7 = 0x80 ;
47  
48      
49      public static void main( String[] args )
50      {
51          junit.textui.TestRunner.run( TagTest.class ) ;
52      }
53  
54      
55      /*
56       * @see TestCase#setUp()
57       */
58      protected void setUp() throws Exception
59      {
60          super.setUp();
61      }
62  
63      
64      /*
65       * @see TestCase#tearDown()
66       */
67      protected void tearDown() throws Exception
68      {
69          super.tearDown();
70      }
71  
72      
73      /***
74       * Constructor for TagTest.
75       * @param arg0
76       */
77      public TagTest(String arg0)
78      {
79          super(arg0);
80      }
81      
82      
83      public void getTypeClass()
84      {
85          assertEquals( TypeClass.UNIVERSAL, TypeClass.getTypeClass( 0 ) ) ;
86      }
87      
88      
89      public void testIsPrimitive() throws Exception
90      {
91          byte octet = BIT_5 ;
92          
93          assertFalse( Tag.isPrimitive( octet ) ) ;
94          assertFalse( Tag.isPrimitive( BIT_5 ) ) ;
95          
96          assertTrue( Tag.isPrimitive( 0 ) ) ;
97          assertTrue( Tag.isPrimitive( BIT_0 ) ) ;
98          assertTrue( Tag.isPrimitive( BIT_1 ) ) ;
99          assertTrue( Tag.isPrimitive( BIT_2 ) ) ;
100         assertTrue( Tag.isPrimitive( BIT_3 ) ) ;
101         assertTrue( Tag.isPrimitive( BIT_4 ) ) ;
102         assertTrue( Tag.isPrimitive( BIT_6 ) ) ;
103         assertTrue( Tag.isPrimitive( BIT_7 ) ) ;
104     }
105 
106 
107     public void testIsConstructed() throws Exception
108     {
109         byte octet = BIT_5 ;
110         
111         assertTrue( Tag.isConstructed( octet ) ) ;
112         assertTrue( Tag.isConstructed( BIT_5 ) ) ;
113         
114         assertFalse( Tag.isConstructed( 0 ) ) ;
115         assertFalse( Tag.isConstructed( BIT_0 ) ) ;
116         assertFalse( Tag.isConstructed( BIT_1 ) ) ;
117         assertFalse( Tag.isConstructed( BIT_2 ) ) ;
118         assertFalse( Tag.isConstructed( BIT_3 ) ) ;
119         assertFalse( Tag.isConstructed( BIT_4 ) ) ;
120         assertFalse( Tag.isConstructed( BIT_6 ) ) ;
121         assertFalse( Tag.isConstructed( BIT_7 ) ) ;
122     }
123     
124     
125     public void testGetTagIdInt() throws Exception
126     {
127         int rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 0, false );
128         assertEquals( Tag.getTagId( rawTag ), 0 );
129 
130         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 3, false );
131         assertEquals( Tag.getTagId( rawTag ), 3 );
132 
133         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 30, false );
134         assertEquals( Tag.getTagId( rawTag ), 30 );
135 
136         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 31, false );
137         assertEquals( Tag.getTagId( rawTag ), 31 );
138 
139         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 126, false );
140         assertEquals( Tag.getTagId( rawTag ), 126 );
141 
142         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 127, false );
143         assertEquals( Tag.getTagId( rawTag ), 127 );
144 
145         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 128, false );
146         assertEquals( Tag.getTagId( rawTag ), 128 );
147 
148         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 16382, false );
149         assertEquals( Tag.getTagId( rawTag ), 16382 );
150 
151         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 16383, false );
152         assertEquals( Tag.getTagId( rawTag ), 16383 );
153 
154         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 16384, false );
155         assertEquals( Tag.getTagId( rawTag ), 16384 );
156 
157         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 2097150, false );
158         assertEquals( Tag.getTagId( rawTag ), 2097150 );
159 
160         rawTag = Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 2097151, false );
161         assertEquals( Tag.getTagId( rawTag ), 2097151 );
162     }
163 
164 
165     public void testGetTagIdByteArray() throws Exception
166     {
167         byte[] octets = new byte[1] ;
168 
169         for ( int ii = 0 ; ii < 128; ii++ )
170         {
171             octets[0] = ( byte ) ii ;
172 
173             if ( ii < 31 )
174             {
175                 assertEquals( Tag.getTagId( octets ), ii ) ;
176             }
177             else
178             {
179                 assertTrue( Tag.getTagId( octets ) != ii ) ;
180             }
181         }
182 
183         octets = new byte[2] ;
184         octets[0] = 31 ;
185         octets[1] = 0 ;
186 
187         for ( int ii = 31 ; ii < 255; ii++ )
188         {
189             octets[1] = ( byte ) ii ;
190 
191             if ( ii < 128 )
192             {
193                 assertEquals( Tag.getTagId( octets ), ii ) ;
194             }
195             else
196             {
197                 assertTrue( Tag.getTagId( octets ) != ii ) ;
198             }
199         }
200 
201         octets = new byte[3] ;
202         octets[0] = 31 ;
203         octets[1] = 0 ;
204         octets[2] = 0 ;
205 
206         for ( int ii = 128 ; ii < 20000; ii++ )
207         {
208             octets[1] = (byte)((ii >> 7) & Tag.LONG_MASK);
209             octets[2] = (byte)(ii & Tag.LONG_MASK);
210 
211             if ( ii < 16384 )
212             {
213                 assertEquals( Tag.getTagId( octets ), ii ) ;
214             }
215             else
216             {
217                 assertTrue( Tag.getTagId( octets ) != ii ) ;
218             }
219         }
220 
221         octets = new byte[4] ;
222         octets[0] = 31 ;
223         octets[1] = 0 ; // shift 0
224         octets[2] = 0 ; // shift 7
225         octets[3] = 0 ; // shift 14
226 
227         for ( int ii = 16384 ; ii < 2100000 ; ii++ )
228         {
229             octets[1] = (byte)((ii >> 14) & Tag.LONG_MASK);
230             octets[2] = (byte)((ii >> 7) & Tag.LONG_MASK);
231             octets[3] = (byte)(ii & Tag.LONG_MASK);
232 
233             if ( ii < 2097152 )
234             {
235                 assertEquals( Tag.getTagId( octets ), ii ) ;
236             }
237             else
238             {
239                 assertTrue( Tag.getTagId( octets ) != ii ) ;
240             }
241         }
242 
243         try
244         {
245             Tag.getTagId( new byte[5] ) ;
246             fail( "should fail before getting here" ) ;
247         }
248         catch ( Throwable t )
249         {
250             assertNotNull( t ) ;
251         }
252 
253 
254         try
255         {
256             Tag.getTagId( new byte[12] ) ;
257             fail( "should fail before getting here" ) ;
258         }
259         catch ( Throwable t )
260         {
261             assertNotNull( t ) ;
262         }
263     }
264 
265 
266     public void testIsRawTagConstructed()
267     {
268         int rawTag = Tag.getIntEncodedTag( TypeClass.APPLICATION, 1234, true );
269         assertTrue( Tag.isRawTagConstructed( rawTag ) );
270 
271         rawTag = Tag.getIntEncodedTag( TypeClass.APPLICATION, 1234, false );
272         assertFalse( Tag.isRawTagConstructed( rawTag ) );
273 
274         rawTag = Tag.getIntEncodedTag( TypeClass.CONTEXT_SPECIFIC, 128, true );
275         assertTrue( Tag.isRawTagConstructed( rawTag ) );
276 
277         rawTag = Tag.getIntEncodedTag( TypeClass.PRIVATE, 234, false );
278         assertFalse( Tag.isRawTagConstructed( rawTag ) );
279     }
280 
281 
282     public void testTagLimits() throws Exception
283     {
284         byte[] bites = { (byte) 0xff, (byte) 0xff, (byte) 0x8f, (byte) 0x0f } ;
285 
286         Tag tag = new Tag() ;
287         tag.add( bites[0] ) ;
288         tag.add( bites[1] ) ;
289         tag.add( bites[2] ) ;
290         tag.add( bites[3] ) ;
291 
292         byte[] octets = tag.getOctets() ;
293         assertTrue( ArrayUtils.isEquals( bites, octets ) ) ;
294 
295         byte[] tooMany = { (byte) 0xff, (byte) 0xff, (byte) 0x8f, (byte) 0x8f, (byte) 0x0f } ;
296 
297         tag = new Tag() ;
298         tag.add( tooMany[0] ) ;
299         tag.add( tooMany[1] ) ;
300         tag.add( tooMany[2] ) ;
301         tag.add( tooMany[3] ) ;
302 
303         try
304         {
305             tag.add( tooMany[4] ) ;
306             fail( "should never get here due to exception" ) ;
307         }
308         catch( BufferOverflowException e )
309         {
310         }
311     }
312 
313 
314     public void testGetOctets() throws Exception
315     {
316         byte[] bites = { (byte) 0xff, (byte) 0xff, (byte) 0x0f } ;
317         
318         Tag tag = new Tag() ;
319         tag.add( bites[0] ) ;
320         tag.add( bites[1] ) ;
321         tag.add( bites[2] ) ;
322         
323         byte[] octets = tag.getOctets() ;
324         assertTrue( ArrayUtils.isEquals( bites, octets ) ) ;
325     }
326     
327     
328     public void testGetOctets2() throws Exception
329     {
330         byte[] bites = { (byte) 0x00, (byte) 0xff } ;
331         
332         Tag tag = new Tag() ;
333         tag.add( bites[0] ) ;
334         
335         try
336         {
337             tag.add( bites[1] ) ;
338             fail( "should never get here due to illegal state" ) ;
339         }
340         catch ( Throwable t ) 
341         {
342             assertNotNull( t ) ;
343         }
344     }
345 
346 
347     public void testGetIntEncodedTag()
348     {
349         assertEquals( UniversalTag.INTEGER.getPrimitiveTag(),
350                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL,
351                         UniversalTag.INTEGER.getTagId(), false ) ) ;
352 
353         assertEquals( 0x01000000,
354                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 1, false ) ) ;
355 
356         assertEquals( 0x0F000000,
357                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 15, false ) ) ;
358 
359         assertEquals( 0x1E000000,
360                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 30, false ) ) ;
361 
362         assertEquals( 0x1F1F0000,
363                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 31, false ) ) ;
364 
365         assertEquals( 0x1F7E0000,
366                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 126, false ) ) ;
367 
368         assertEquals( 0x1F7F0000,
369                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 127, false ) ) ;
370 
371         assertEquals( 0x1F810000,
372                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 128, false ) ) ;
373 
374         assertEquals( 0x1F810100,
375                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, 129, false ) ) ;
376 
377         assertEquals( 0x3FFF7E00,
378                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, (1<<14)-2, true ) ) ;
379 
380         assertEquals( 0x1FFF7F00,
381                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, (1<<14)-1, false ) ) ;
382 
383         assertEquals( 0xDF818000,
384                 Tag.getIntEncodedTag( TypeClass.PRIVATE, (1<<14), false ) ) ;
385 
386         assertEquals( 0x5F818001,
387                 Tag.getIntEncodedTag( TypeClass.APPLICATION, (1<<14)+1, false ) ) ;
388 
389         assertEquals( 0x9FFFFF7E,
390                 Tag.getIntEncodedTag( TypeClass.CONTEXT_SPECIFIC,
391                         (1<<21)-2, false ) ) ;
392 
393         assertEquals( 0x1FFFFF7F,
394                 Tag.getIntEncodedTag( TypeClass.UNIVERSAL, (1<<21)-1, false ) ) ;
395 
396         try
397         {
398             Tag.getIntEncodedTag( TypeClass.UNIVERSAL, (1<<21), false ) ;
399             fail( "should never get here due to an exception" ) ;
400         }
401         catch( IllegalArgumentException e )
402         {
403         }
404     }
405 }