View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  
19  package org.apache.commons.compress.archivers.zip;
20  
21  import junit.framework.TestCase;
22  
23  /**
24   * JUnit 3 testcases for org.apache.commons.compress.archivers.zip.ExtraFieldUtils.
25   *
26   */
27  public class ExtraFieldUtilsTest extends TestCase implements UnixStat {
28      public ExtraFieldUtilsTest(String name) {
29          super(name);
30      }
31  
32      /**
33       * Header-ID of a ZipExtraField not supported by Commons Compress.
34       *
35       * <p>Used to be ZipShort(1) but this is the ID of the Zip64 extra
36       * field.</p>
37       */
38      static final ZipShort UNRECOGNIZED_HEADER = new ZipShort(0x5555);
39  
40      private AsiExtraField a;
41      private UnrecognizedExtraField dummy;
42      private byte[] data;
43      private byte[] aLocal;
44  
45      @Override
46      public void setUp() {
47          a = new AsiExtraField();
48          a.setMode(0755);
49          a.setDirectory(true);
50          dummy = new UnrecognizedExtraField();
51          dummy.setHeaderId(UNRECOGNIZED_HEADER);
52          dummy.setLocalFileDataData(new byte[] {0});
53          dummy.setCentralDirectoryData(new byte[] {0});
54  
55          aLocal = a.getLocalFileDataData();
56          byte[] dummyLocal = dummy.getLocalFileDataData();
57          data = new byte[4 + aLocal.length + 4 + dummyLocal.length];
58          System.arraycopy(a.getHeaderId().getBytes(), 0, data, 0, 2);
59          System.arraycopy(a.getLocalFileDataLength().getBytes(), 0, data, 2, 2);
60          System.arraycopy(aLocal, 0, data, 4, aLocal.length);
61          System.arraycopy(dummy.getHeaderId().getBytes(), 0, data,
62                           4+aLocal.length, 2);
63          System.arraycopy(dummy.getLocalFileDataLength().getBytes(), 0, data,
64                           4+aLocal.length+2, 2);
65          System.arraycopy(dummyLocal, 0, data,
66                           4+aLocal.length+4, dummyLocal.length);
67  
68      }
69  
70      /**
71       * test parser.
72       */
73      public void testParse() throws Exception {
74          ZipExtraField[] ze = ExtraFieldUtils.parse(data);
75          assertEquals("number of fields", 2, ze.length);
76          assertTrue("type field 1", ze[0] instanceof AsiExtraField);
77          assertEquals("mode field 1", 040755,
78                       ((AsiExtraField) ze[0]).getMode());
79          assertTrue("type field 2", ze[1] instanceof UnrecognizedExtraField);
80          assertEquals("data length field 2", 1,
81                       ze[1].getLocalFileDataLength().getValue());
82  
83          byte[] data2 = new byte[data.length-1];
84          System.arraycopy(data, 0, data2, 0, data2.length);
85          try {
86              ExtraFieldUtils.parse(data2);
87              fail("data should be invalid");
88          } catch (Exception e) {
89              assertEquals("message",
90                           "bad extra field starting at "+(4 + aLocal.length)
91                           + ".  Block length of 1 bytes exceeds remaining data of 0 bytes.",
92                           e.getMessage());
93          }
94      }
95  
96      public void testParseWithRead() throws Exception {
97          ZipExtraField[] ze =
98              ExtraFieldUtils.parse(data, true,
99                                    ExtraFieldUtils.UnparseableExtraField.READ);
100         assertEquals("number of fields", 2, ze.length);
101         assertTrue("type field 1", ze[0] instanceof AsiExtraField);
102         assertEquals("mode field 1", 040755,
103                      ((AsiExtraField) ze[0]).getMode());
104         assertTrue("type field 2", ze[1] instanceof UnrecognizedExtraField);
105         assertEquals("data length field 2", 1,
106                      ze[1].getLocalFileDataLength().getValue());
107 
108         byte[] data2 = new byte[data.length-1];
109         System.arraycopy(data, 0, data2, 0, data2.length);
110         ze = ExtraFieldUtils.parse(data2, true,
111                                    ExtraFieldUtils.UnparseableExtraField.READ);
112         assertEquals("number of fields", 2, ze.length);
113         assertTrue("type field 1", ze[0] instanceof AsiExtraField);
114         assertEquals("mode field 1", 040755,
115                      ((AsiExtraField) ze[0]).getMode());
116         assertTrue("type field 2", ze[1] instanceof UnparseableExtraFieldData);
117         assertEquals("data length field 2", 4,
118                      ze[1].getLocalFileDataLength().getValue());
119         for (int i = 0; i < 4; i++) {
120             assertEquals("byte number " + i,
121                          data2[data.length - 5 + i],
122                          ze[1].getLocalFileDataData()[i]);
123         }
124     }
125 
126     public void testParseWithSkip() throws Exception {
127         ZipExtraField[] ze =
128             ExtraFieldUtils.parse(data, true,
129                                   ExtraFieldUtils.UnparseableExtraField.SKIP);
130         assertEquals("number of fields", 2, ze.length);
131         assertTrue("type field 1", ze[0] instanceof AsiExtraField);
132         assertEquals("mode field 1", 040755,
133                      ((AsiExtraField) ze[0]).getMode());
134         assertTrue("type field 2", ze[1] instanceof UnrecognizedExtraField);
135         assertEquals("data length field 2", 1,
136                      ze[1].getLocalFileDataLength().getValue());
137 
138         byte[] data2 = new byte[data.length-1];
139         System.arraycopy(data, 0, data2, 0, data2.length);
140         ze = ExtraFieldUtils.parse(data2, true,
141                                    ExtraFieldUtils.UnparseableExtraField.SKIP);
142         assertEquals("number of fields", 1, ze.length);
143         assertTrue("type field 1", ze[0] instanceof AsiExtraField);
144         assertEquals("mode field 1", 040755,
145                      ((AsiExtraField) ze[0]).getMode());
146     }
147 
148     /**
149      * Test merge methods
150      */
151     public void testMerge() {
152         byte[] local =
153             ExtraFieldUtils.mergeLocalFileDataData(new ZipExtraField[] {a, dummy});
154         assertEquals("local length", data.length, local.length);
155         for (int i=0; i<local.length; i++) {
156             assertEquals("local byte "+i, data[i], local[i]);
157         }
158 
159         byte[] dummyCentral = dummy.getCentralDirectoryData();
160         byte[] data2 = new byte[4 + aLocal.length + 4 + dummyCentral.length];
161         System.arraycopy(data, 0, data2, 0, 4 + aLocal.length + 2);
162         System.arraycopy(dummy.getCentralDirectoryLength().getBytes(), 0,
163                          data2, 4+aLocal.length+2, 2);
164         System.arraycopy(dummyCentral, 0, data2,
165                          4+aLocal.length+4, dummyCentral.length);
166 
167 
168         byte[] central =
169             ExtraFieldUtils.mergeCentralDirectoryData(new ZipExtraField[] {a, dummy});
170         assertEquals("central length", data2.length, central.length);
171         for (int i=0; i<central.length; i++) {
172             assertEquals("central byte "+i, data2[i], central[i]);
173         }
174 
175     }
176 
177     public void testMergeWithUnparseableData() throws Exception {
178         ZipExtraField d = new UnparseableExtraFieldData();
179         byte[] b = UNRECOGNIZED_HEADER.getBytes();
180         d.parseFromLocalFileData(new byte[] {b[0], b[1], 1, 0}, 0, 4);
181         byte[] local =
182             ExtraFieldUtils.mergeLocalFileDataData(new ZipExtraField[] {a, d});
183         assertEquals("local length", data.length - 1, local.length);
184         for (int i = 0; i < local.length; i++) {
185             assertEquals("local byte " + i, data[i], local[i]);
186         }
187 
188         byte[] dCentral = d.getCentralDirectoryData();
189         byte[] data2 = new byte[4 + aLocal.length + dCentral.length];
190         System.arraycopy(data, 0, data2, 0, 4 + aLocal.length + 2);
191         System.arraycopy(dCentral, 0, data2,
192                          4 + aLocal.length, dCentral.length);
193 
194 
195         byte[] central =
196             ExtraFieldUtils.mergeCentralDirectoryData(new ZipExtraField[] {a, d});
197         assertEquals("central length", data2.length, central.length);
198         for (int i = 0; i < central.length; i++) {
199             assertEquals("central byte " + i, data2[i], central[i]);
200         }
201 
202     }
203 }