Advertisement
Guest User

MemoryHeaderReader

a guest
Apr 23rd, 2016
401
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 24.87 KB | None | 0 0
  1. package com.example.zip;
  2.  
  3. import net.lingala.zip4j.exception.ZipException;
  4. import net.lingala.zip4j.exception.ZipExceptionConstants;
  5. import net.lingala.zip4j.model.*;
  6. import net.lingala.zip4j.util.InternalZipConstants;
  7. import net.lingala.zip4j.util.Raw;
  8. import net.lingala.zip4j.util.Zip4jConstants;
  9. import net.lingala.zip4j.util.Zip4jUtil;
  10.  
  11. import java.io.IOException;
  12. import java.util.ArrayList;
  13.  
  14. /*
  15. This file is a derivative of HeaderReader class from zip4j-1.3.2 library.
  16. The original sources can be retrieved at http://www.lingala.net/zip4j/ .
  17.  
  18. Licensed under the Apache License, Version 2.0 (the "License");
  19. you may not use this file except in compliance with the License.
  20. You may obtain a copy of the License at
  21.  
  22.     http://www.apache.org/licenses/LICENSE-2.0
  23.  
  24. Unless required by applicable law or agreed to in writing, software
  25. distributed under the License is distributed on an "AS IS" BASIS,
  26. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27. See the License for the specific language governing permissions and
  28. limitations under the License.
  29.  */
  30.  
  31. public class MemoryHeaderReader {
  32.  
  33.     private RandomAccessStream zip4jRaf = null;
  34.     private ZipModel zipModel;
  35.  
  36.     public MemoryHeaderReader(RandomAccessStream zip4jRaf) throws ZipException {
  37.         if (zip4jRaf == null) {
  38.             throw new ZipException("random access file was null", ZipExceptionConstants.randomAccessFileNull);
  39.         }
  40.         this.zip4jRaf = zip4jRaf;
  41.     }
  42.  
  43.     public ZipModel readAllHeaders() throws ZipException {
  44.         zipModel = new ZipModel();
  45.         zipModel.setEndCentralDirRecord(readEndOfCentralDirectoryRecord());
  46.         zipModel.setCentralDirectory(readCentralDirectory());
  47.         return zipModel;
  48.     }
  49.  
  50.     /**
  51.      * Reads end of central directory record
  52.      * @return {@link EndCentralDirRecord}
  53.      * @throws ZipException
  54.      */
  55.     private EndCentralDirRecord readEndOfCentralDirectoryRecord() throws ZipException {
  56.         try {
  57.             byte[] ebs = new byte[4];
  58.             long pos = zip4jRaf.length() - InternalZipConstants.ENDHDR;
  59.  
  60.             EndCentralDirRecord endCentralDirRecord = new EndCentralDirRecord();
  61.             int counter = 0;
  62.             do {
  63.                 zip4jRaf.seek(pos--);
  64.                 counter++;
  65.             } while ((Raw.readLeInt(zip4jRaf, ebs) != InternalZipConstants.ENDSIG) && counter <= 3000);
  66.  
  67.             if ((Raw.readIntLittleEndian(ebs, 0) != InternalZipConstants.ENDSIG)) {
  68.                 throw new ZipException("zip headers not found. probably not a zip file");
  69.             }
  70.             byte[] intBuff = new byte[4];
  71.             byte[] shortBuff = new byte[2];
  72.  
  73.             //End of central record signature
  74.             endCentralDirRecord.setSignature(InternalZipConstants.ENDSIG);
  75.  
  76.             //number of this disk
  77.             readIntoBuff(zip4jRaf, shortBuff);
  78.             endCentralDirRecord.setNoOfThisDisk(Raw.readShortLittleEndian(shortBuff, 0));
  79.  
  80.             //number of the disk with the start of the central directory
  81.             readIntoBuff(zip4jRaf, shortBuff);
  82.             endCentralDirRecord.setNoOfThisDiskStartOfCentralDir(Raw.readShortLittleEndian(shortBuff, 0));
  83.  
  84.             //total number of entries in the central directory on this disk
  85.             readIntoBuff(zip4jRaf, shortBuff);
  86.             endCentralDirRecord.setTotNoOfEntriesInCentralDirOnThisDisk(Raw.readShortLittleEndian(shortBuff, 0));
  87.  
  88.             //total number of entries in the central directory
  89.             readIntoBuff(zip4jRaf, shortBuff);
  90.             endCentralDirRecord.setTotNoOfEntriesInCentralDir(Raw.readShortLittleEndian(shortBuff, 0));
  91.  
  92.             //size of the central directory
  93.             readIntoBuff(zip4jRaf, intBuff);
  94.             endCentralDirRecord.setSizeOfCentralDir(Raw.readIntLittleEndian(intBuff, 0));
  95.  
  96.             //offset of start of central directory with respect to the starting disk number
  97.             readIntoBuff(zip4jRaf, intBuff);
  98.             byte[] longBuff = getLongByteFromIntByte(intBuff);
  99.             endCentralDirRecord.setOffsetOfStartOfCentralDir(Raw.readLongLittleEndian(longBuff, 0));
  100.  
  101.             //.ZIP file comment length
  102.             readIntoBuff(zip4jRaf, shortBuff);
  103.             int commentLength = Raw.readShortLittleEndian(shortBuff, 0);
  104.             endCentralDirRecord.setCommentLength(commentLength);
  105.  
  106.             //.ZIP file comment
  107.             if (commentLength > 0) {
  108.                 byte[] commentBuf = new byte[commentLength];
  109.                 readIntoBuff(zip4jRaf, commentBuf);
  110.                 endCentralDirRecord.setComment(new String(commentBuf));
  111.                 endCentralDirRecord.setCommentBytes(commentBuf);
  112.             } else {
  113.                 endCentralDirRecord.setComment(null);
  114.             }
  115.  
  116.             int diskNumber = endCentralDirRecord.getNoOfThisDisk();
  117.             if (diskNumber > 0) {
  118.                 zipModel.setSplitArchive(true);
  119.             } else {
  120.                 zipModel.setSplitArchive(false);
  121.             }
  122.  
  123.             return endCentralDirRecord;
  124.         } catch (RuntimeException e) {
  125.             throw new ZipException("Probably not a zip file or a corrupted zip file", e, ZipExceptionConstants.notZipFile);
  126.         }
  127.     }
  128.  
  129.     /**
  130.      * Reads central directory information for the zip file
  131.      * @return {@link CentralDirectory}
  132.      * @throws ZipException
  133.      */
  134.     private CentralDirectory readCentralDirectory() throws ZipException {
  135.         if (zipModel.getEndCentralDirRecord() == null) {
  136.             throw new ZipException("EndCentralRecord was null, maybe a corrupt zip file");
  137.         }
  138.  
  139.         try {
  140.             CentralDirectory centralDirectory = new CentralDirectory();
  141.             ArrayList fileHeaderList = new ArrayList();
  142.  
  143.             EndCentralDirRecord endCentralDirRecord = zipModel.getEndCentralDirRecord();
  144.             long offSetStartCentralDir = endCentralDirRecord.getOffsetOfStartOfCentralDir();
  145.             int centralDirEntryCount = endCentralDirRecord.getTotNoOfEntriesInCentralDir();
  146.  
  147.             if (zipModel.isZip64Format()) {
  148.                 offSetStartCentralDir = zipModel.getZip64EndCentralDirRecord().getOffsetStartCenDirWRTStartDiskNo();
  149.                 centralDirEntryCount = (int) zipModel.getZip64EndCentralDirRecord().getTotNoOfEntriesInCentralDir();
  150.             }
  151.  
  152.             zip4jRaf.seek(offSetStartCentralDir);
  153.  
  154.             byte[] intBuff = new byte[4];
  155.             byte[] shortBuff = new byte[2];
  156.             byte[] longBuff = new byte[8];
  157.  
  158.             for (int i = 0; i < centralDirEntryCount; i++) {
  159.                 FileHeader fileHeader = new FileHeader();
  160.  
  161.                 //FileHeader Signature
  162.                 readIntoBuff(zip4jRaf, intBuff);
  163.                 int signature = Raw.readIntLittleEndian(intBuff, 0);
  164.                 if (signature != InternalZipConstants.CENSIG) {
  165.                     throw new ZipException("Expected central directory entry not found (#" + (i + 1) + ")");
  166.                 }
  167.                 fileHeader.setSignature(signature);
  168.  
  169.                 //version made by
  170.                 readIntoBuff(zip4jRaf, shortBuff);
  171.                 fileHeader.setVersionMadeBy(Raw.readShortLittleEndian(shortBuff, 0));
  172.  
  173.                 //version needed to extract
  174.                 readIntoBuff(zip4jRaf, shortBuff);
  175.                 fileHeader.setVersionNeededToExtract(Raw.readShortLittleEndian(shortBuff, 0));
  176.  
  177.                 //general purpose bit flag
  178.                 readIntoBuff(zip4jRaf, shortBuff);
  179.                 fileHeader.setFileNameUTF8Encoded((Raw.readShortLittleEndian(shortBuff, 0) & InternalZipConstants.UFT8_NAMES_FLAG) != 0);
  180.                 int firstByte = shortBuff[0];
  181.                 int result = firstByte & 1;
  182.                 if (result != 0) {
  183.                     fileHeader.setEncrypted(true);
  184.                 }
  185.                 fileHeader.setGeneralPurposeFlag((byte[]) shortBuff.clone());
  186.  
  187.                 //Check if data descriptor exists for local file header
  188.                 fileHeader.setDataDescriptorExists(firstByte >> 3 == 1);
  189.  
  190.                 //compression method
  191.                 readIntoBuff(zip4jRaf, shortBuff);
  192.                 fileHeader.setCompressionMethod(Raw.readShortLittleEndian(shortBuff, 0));
  193.  
  194.                 //last mod file time
  195.                 readIntoBuff(zip4jRaf, intBuff);
  196.                 fileHeader.setLastModFileTime(Raw.readIntLittleEndian(intBuff, 0));
  197.  
  198.                 //crc-32
  199.                 readIntoBuff(zip4jRaf, intBuff);
  200.                 fileHeader.setCrc32(Raw.readIntLittleEndian(intBuff, 0));
  201.                 fileHeader.setCrcBuff((byte[]) intBuff.clone());
  202.  
  203.                 //compressed size
  204.                 readIntoBuff(zip4jRaf, intBuff);
  205.                 longBuff = getLongByteFromIntByte(intBuff);
  206.                 fileHeader.setCompressedSize(Raw.readLongLittleEndian(longBuff, 0));
  207.  
  208.                 //uncompressed size
  209.                 readIntoBuff(zip4jRaf, intBuff);
  210.                 longBuff = getLongByteFromIntByte(intBuff);
  211.                 fileHeader.setUncompressedSize(Raw.readLongLittleEndian(longBuff, 0));
  212.  
  213.                 //file name length
  214.                 readIntoBuff(zip4jRaf, shortBuff);
  215.                 int fileNameLength = Raw.readShortLittleEndian(shortBuff, 0);
  216.                 fileHeader.setFileNameLength(fileNameLength);
  217.  
  218.                 //extra field length
  219.                 readIntoBuff(zip4jRaf, shortBuff);
  220.                 int extraFieldLength = Raw.readShortLittleEndian(shortBuff, 0);
  221.                 fileHeader.setExtraFieldLength(extraFieldLength);
  222.  
  223.                 //file comment length
  224.                 readIntoBuff(zip4jRaf, shortBuff);
  225.                 int fileCommentLength = Raw.readShortLittleEndian(shortBuff, 0);
  226.                 fileHeader.setFileComment(new String(shortBuff));
  227.  
  228.                 //disk number start
  229.                 readIntoBuff(zip4jRaf, shortBuff);
  230.                 fileHeader.setDiskNumberStart(Raw.readShortLittleEndian(shortBuff, 0));
  231.  
  232.                 //internal file attributes
  233.                 readIntoBuff(zip4jRaf, shortBuff);
  234.                 fileHeader.setInternalFileAttr((byte[]) shortBuff.clone());
  235.  
  236.                 //external file attributes
  237.                 readIntoBuff(zip4jRaf, intBuff);
  238.                 fileHeader.setExternalFileAttr((byte[]) intBuff.clone());
  239.  
  240.                 //relative offset of local header
  241.                 readIntoBuff(zip4jRaf, intBuff);
  242.                 //Commented on 26.08.2010. Revert back if any issues
  243.                 //fileHeader.setOffsetLocalHeader((Raw.readIntLittleEndian(intBuff, 0) & 0xFFFFFFFFL) + zip4jRaf.getStart());
  244.                 longBuff = getLongByteFromIntByte(intBuff);
  245.                 fileHeader.setOffsetLocalHeader((Raw.readLongLittleEndian(longBuff, 0) & 0xFFFFFFFFL));
  246.  
  247.                 if (fileNameLength > 0) {
  248.                     byte[] fileNameBuf = new byte[fileNameLength];
  249.                     readIntoBuff(zip4jRaf, fileNameBuf);
  250.                     // Modified after user reported an issue http://www.lingala.net/zip4j/forum/index.php?topic=2.0
  251.                     //                  String fileName = new String(fileNameBuf, "Cp850");
  252.                     // Modified as per http://www.lingala.net/zip4j/forum/index.php?topic=41.0
  253.                     //                  String fileName = Zip4jUtil.getCp850EncodedString(fileNameBuf);
  254.  
  255.                     String fileName = null;
  256.  
  257.                     if (Zip4jUtil.isStringNotNullAndNotEmpty(zipModel.getFileNameCharset())) {
  258.                         fileName = new String(fileNameBuf, zipModel.getFileNameCharset());
  259.                     } else {
  260.                         fileName = Zip4jUtil.decodeFileName(fileNameBuf, fileHeader.isFileNameUTF8Encoded());
  261.                     }
  262.  
  263.                     if (fileName == null) {
  264.                         throw new ZipException("fileName is null when reading central directory");
  265.                     }
  266.  
  267.                     if (fileName.indexOf(":" + System.getProperty("file.separator")) >= 0) {
  268.                         fileName = fileName.substring(fileName.indexOf(":" + System.getProperty("file.separator")) + 2);
  269.                     }
  270.  
  271.                     fileHeader.setFileName(fileName);
  272.                     fileHeader.setDirectory(fileName.endsWith("/") || fileName.endsWith("\\"));
  273.  
  274.                 } else {
  275.                     fileHeader.setFileName(null);
  276.                 }
  277.  
  278.                 //Extra field
  279.                 readAndSaveExtraDataRecord(fileHeader);
  280.  
  281.                 //Read Zip64 Extra data records if exists
  282.                 readAndSaveZip64ExtendedInfo(fileHeader);
  283.  
  284.                 //Read AES Extra Data record if exists
  285.                 readAndSaveAESExtraDataRecord(fileHeader);
  286.  
  287.                 if (fileCommentLength > 0) {
  288.                     byte[] fileCommentBuf = new byte[fileCommentLength];
  289.                     readIntoBuff(zip4jRaf, fileCommentBuf);
  290.                     fileHeader.setFileComment(new String(fileCommentBuf));
  291.                 }
  292.  
  293.                 fileHeaderList.add(fileHeader);
  294.             }
  295.             centralDirectory.setFileHeaders(fileHeaderList);
  296.  
  297.             //Digital Signature
  298.             DigitalSignature digitalSignature = new DigitalSignature();
  299.             readIntoBuff(zip4jRaf, intBuff);
  300.             int signature = Raw.readIntLittleEndian(intBuff, 0);
  301.             if (signature != InternalZipConstants.DIGSIG) {
  302.                 return centralDirectory;
  303.             }
  304.  
  305.             digitalSignature.setHeaderSignature(signature);
  306.  
  307.             //size of data
  308.             readIntoBuff(zip4jRaf, shortBuff);
  309.             int sizeOfData = Raw.readShortLittleEndian(shortBuff, 0);
  310.             digitalSignature.setSizeOfData(sizeOfData);
  311.  
  312.             if (sizeOfData > 0) {
  313.                 byte[] sigDataBuf = new byte[sizeOfData];
  314.                 readIntoBuff(zip4jRaf, sigDataBuf);
  315.                 digitalSignature.setSignatureData(new String(sigDataBuf));
  316.             }
  317.  
  318.             return centralDirectory;
  319.         } catch (IOException e) {
  320.             throw new ZipException(e);
  321.         }
  322.     }
  323.  
  324.     /**
  325.      * Reads extra data record and saves it in the {@link FileHeader}
  326.      * @param fileHeader
  327.      * @throws ZipException
  328.      */
  329.     private void readAndSaveExtraDataRecord(FileHeader fileHeader) throws ZipException {
  330.         if (fileHeader == null) {
  331.             throw new ZipException("file header is null");
  332.         }
  333.  
  334.         int extraFieldLength = fileHeader.getExtraFieldLength();
  335.         if (extraFieldLength <= 0) {
  336.             return;
  337.         }
  338.  
  339.         fileHeader.setExtraDataRecords(readExtraDataRecords(extraFieldLength));
  340.  
  341.     }
  342.  
  343.     /**
  344.      * Reads extra data records
  345.      * @param extraFieldLength
  346.      * @return ArrayList of {@link ExtraDataRecord}
  347.      * @throws ZipException
  348.      */
  349.     private ArrayList readExtraDataRecords(int extraFieldLength) throws ZipException {
  350.         if (extraFieldLength <= 0) {
  351.             return null;
  352.         }
  353.  
  354.         try {
  355.             byte[] extraFieldBuf = new byte[extraFieldLength];
  356.             zip4jRaf.read(extraFieldBuf);
  357.  
  358.             int counter = 0;
  359.             ArrayList extraDataList = new ArrayList();
  360.             while (counter < extraFieldLength) {
  361.                 ExtraDataRecord extraDataRecord = new ExtraDataRecord();
  362.                 int header = Raw.readShortLittleEndian(extraFieldBuf, counter);
  363.                 extraDataRecord.setHeader(header);
  364.                 counter = counter + 2;
  365.                 int sizeOfRec = Raw.readShortLittleEndian(extraFieldBuf, counter);
  366.  
  367.                 if ((2 + sizeOfRec) > extraFieldLength) {
  368.                     sizeOfRec = Raw.readShortBigEndian(extraFieldBuf, counter);
  369.                     if ((2 + sizeOfRec) > extraFieldLength) {
  370.                         //If this is the case, then extra data record is corrupt
  371.                         //skip reading any further extra data records
  372.                         break;
  373.                     }
  374.                 }
  375.  
  376.                 extraDataRecord.setSizeOfData(sizeOfRec);
  377.                 counter = counter + 2;
  378.  
  379.                 if (sizeOfRec > 0) {
  380.                     byte[] data = new byte[sizeOfRec];
  381.                     System.arraycopy(extraFieldBuf, counter, data, 0, sizeOfRec);
  382.                     extraDataRecord.setData(data);
  383.                 }
  384.                 counter = counter + sizeOfRec;
  385.                 extraDataList.add(extraDataRecord);
  386.             }
  387.             if (extraDataList.size() > 0) {
  388.                 return extraDataList;
  389.             } else {
  390.                 return null;
  391.             }
  392.         } catch (IOException e) {
  393.             throw new ZipException(e);
  394.         }
  395.     }
  396.  
  397.     /**
  398.      * Reads Zip64 Extended info and saves it in the {@link FileHeader}
  399.      * @param fileHeader
  400.      * @throws ZipException
  401.      */
  402.     private void readAndSaveZip64ExtendedInfo(FileHeader fileHeader) throws ZipException {
  403.         if (fileHeader == null) {
  404.             throw new ZipException("file header is null in reading Zip64 Extended Info");
  405.         }
  406.  
  407.         if (fileHeader.getExtraDataRecords() == null || fileHeader.getExtraDataRecords().size() <= 0) {
  408.             return;
  409.         }
  410.  
  411.         Zip64ExtendedInfo zip64ExtendedInfo = readZip64ExtendedInfo(
  412.                 fileHeader.getExtraDataRecords(),
  413.                 fileHeader.getUncompressedSize(),
  414.                 fileHeader.getCompressedSize(),
  415.                 fileHeader.getOffsetLocalHeader(),
  416.                 fileHeader.getDiskNumberStart());
  417.  
  418.         if (zip64ExtendedInfo != null) {
  419.             fileHeader.setZip64ExtendedInfo(zip64ExtendedInfo);
  420.             if (zip64ExtendedInfo.getUnCompressedSize() != -1)
  421.                 fileHeader.setUncompressedSize(zip64ExtendedInfo.getUnCompressedSize());
  422.  
  423.             if (zip64ExtendedInfo.getCompressedSize() != -1)
  424.                 fileHeader.setCompressedSize(zip64ExtendedInfo.getCompressedSize());
  425.  
  426.             if (zip64ExtendedInfo.getOffsetLocalHeader() != -1)
  427.                 fileHeader.setOffsetLocalHeader(zip64ExtendedInfo.getOffsetLocalHeader());
  428.  
  429.             if (zip64ExtendedInfo.getDiskNumberStart() != -1)
  430.                 fileHeader.setDiskNumberStart(zip64ExtendedInfo.getDiskNumberStart());
  431.         }
  432.     }
  433.  
  434.     /**
  435.      * Reads Zip64 Extended Info
  436.      * @param extraDataRecords
  437.      * @param unCompressedSize
  438.      * @param compressedSize
  439.      * @param offsetLocalHeader
  440.      * @param diskNumberStart
  441.      * @return {@link Zip64ExtendedInfo}
  442.      * @throws ZipException
  443.      */
  444.     private Zip64ExtendedInfo readZip64ExtendedInfo(
  445.             ArrayList extraDataRecords,
  446.             long unCompressedSize,
  447.             long compressedSize,
  448.             long offsetLocalHeader,
  449.             int diskNumberStart
  450.     ) {
  451.  
  452.         for (int i = 0; i < extraDataRecords.size(); i++) {
  453.             ExtraDataRecord extraDataRecord = (ExtraDataRecord) extraDataRecords.get(i);
  454.             if (extraDataRecord == null) {
  455.                 continue;
  456.             }
  457.  
  458.             if (extraDataRecord.getHeader() == 0x0001) {
  459.  
  460.                 Zip64ExtendedInfo zip64ExtendedInfo = new Zip64ExtendedInfo();
  461.  
  462.                 byte[] byteBuff = extraDataRecord.getData();
  463.  
  464.                 if (extraDataRecord.getSizeOfData() <= 0) {
  465.                     break;
  466.                 }
  467.                 byte[] longByteBuff = new byte[8];
  468.                 byte[] intByteBuff = new byte[4];
  469.                 int counter = 0;
  470.                 boolean valueAdded = false;
  471.  
  472.                 if (((unCompressedSize & 0xFFFF) == 0xFFFF) && counter < extraDataRecord.getSizeOfData()) {
  473.                     System.arraycopy(byteBuff, counter, longByteBuff, 0, 8);
  474.                     long val = Raw.readLongLittleEndian(longByteBuff, 0);
  475.                     zip64ExtendedInfo.setUnCompressedSize(val);
  476.                     counter += 8;
  477.                     valueAdded = true;
  478.                 }
  479.  
  480.                 if (((compressedSize & 0xFFFF) == 0xFFFF) && counter < extraDataRecord.getSizeOfData()) {
  481.                     System.arraycopy(byteBuff, counter, longByteBuff, 0, 8);
  482.                     long val = Raw.readLongLittleEndian(longByteBuff, 0);
  483.                     zip64ExtendedInfo.setCompressedSize(val);
  484.                     counter += 8;
  485.                     valueAdded = true;
  486.                 }
  487.  
  488.                 if (((offsetLocalHeader & 0xFFFF) == 0xFFFF) && counter < extraDataRecord.getSizeOfData()) {
  489.                     System.arraycopy(byteBuff, counter, longByteBuff, 0, 8);
  490.                     long val = Raw.readLongLittleEndian(longByteBuff, 0);
  491.                     zip64ExtendedInfo.setOffsetLocalHeader(val);
  492.                     counter += 8;
  493.                     valueAdded = true;
  494.                 }
  495.  
  496.                 if (((diskNumberStart & 0xFFFF) == 0xFFFF) && counter < extraDataRecord.getSizeOfData()) {
  497.                     System.arraycopy(byteBuff, counter, intByteBuff, 0, 4);
  498.                     int val = Raw.readIntLittleEndian(intByteBuff, 0);
  499.                     zip64ExtendedInfo.setDiskNumberStart(val);
  500.                     counter += 8;
  501.                     valueAdded = true;
  502.                 }
  503.  
  504.                 if (valueAdded) {
  505.                     return zip64ExtendedInfo;
  506.                 }
  507.  
  508.                 break;
  509.             }
  510.         }
  511.         return null;
  512.     }
  513.  
  514.  
  515.     /**
  516.      * Reads AES Extra Data Record and saves it in the {@link FileHeader}
  517.      * @param fileHeader
  518.      * @throws ZipException
  519.      */
  520.     private void readAndSaveAESExtraDataRecord(FileHeader fileHeader) throws ZipException {
  521.         if (fileHeader == null) {
  522.             throw new ZipException("file header is null in reading Zip64 Extended Info");
  523.         }
  524.  
  525.         if (fileHeader.getExtraDataRecords() == null || fileHeader.getExtraDataRecords().size() <= 0) {
  526.             return;
  527.         }
  528.  
  529.         AESExtraDataRecord aesExtraDataRecord = readAESExtraDataRecord(fileHeader.getExtraDataRecords());
  530.         if (aesExtraDataRecord != null) {
  531.             fileHeader.setAesExtraDataRecord(aesExtraDataRecord);
  532.             fileHeader.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
  533.         }
  534.     }
  535.  
  536.     /**
  537.      * Reads AES Extra Data Record
  538.      * @param extraDataRecords
  539.      * @return {@link AESExtraDataRecord}
  540.      * @throws ZipException
  541.      */
  542.     private AESExtraDataRecord readAESExtraDataRecord(ArrayList extraDataRecords) throws ZipException {
  543.  
  544.         if (extraDataRecords == null) {
  545.             return null;
  546.         }
  547.  
  548.         for (int i = 0; i < extraDataRecords.size(); i++) {
  549.             ExtraDataRecord extraDataRecord = (ExtraDataRecord) extraDataRecords.get(i);
  550.             if (extraDataRecord == null) {
  551.                 continue;
  552.             }
  553.  
  554.             if (extraDataRecord.getHeader() == InternalZipConstants.AESSIG) {
  555.  
  556.                 if (extraDataRecord.getData() == null) {
  557.                     throw new ZipException("corrput AES extra data records");
  558.                 }
  559.  
  560.                 AESExtraDataRecord aesExtraDataRecord = new AESExtraDataRecord();
  561.  
  562.                 aesExtraDataRecord.setSignature(InternalZipConstants.AESSIG);
  563.                 aesExtraDataRecord.setDataSize(extraDataRecord.getSizeOfData());
  564.  
  565.                 byte[] aesData = extraDataRecord.getData();
  566.                 aesExtraDataRecord.setVersionNumber(Raw.readShortLittleEndian(aesData, 0));
  567.                 byte[] vendorIDBytes = new byte[2];
  568.                 System.arraycopy(aesData, 2, vendorIDBytes, 0, 2);
  569.                 aesExtraDataRecord.setVendorID(new String(vendorIDBytes));
  570.                 aesExtraDataRecord.setAesStrength((int) (aesData[4] & 0xFF));
  571.                 aesExtraDataRecord.setCompressionMethod(Raw.readShortLittleEndian(aesData, 5));
  572.  
  573.                 return aesExtraDataRecord;
  574.             }
  575.         }
  576.  
  577.         return null;
  578.     }
  579.  
  580.     /**
  581.      * Reads buf length of bytes from the input stream to buf
  582.      * @param zip4jRaf
  583.      * @param buf
  584.      * @return byte array
  585.      * @throws ZipException
  586.      */
  587.     private byte[] readIntoBuff(RandomAccessStream zip4jRaf, byte[] buf) throws ZipException {
  588.         try {
  589.             if (zip4jRaf.read(buf, 0, buf.length) != -1) {
  590.                 return buf;
  591.             } else {
  592.                 throw new ZipException("unexpected end of file when reading short buff");
  593.             }
  594.         } catch (IOException e) {
  595.             throw new ZipException("IOException when reading short buff", e);
  596.         }
  597.     }
  598.  
  599.     /**
  600.      * Returns a long byte from an int byte by appending last 4 bytes as 0's
  601.      * @param intByte
  602.      * @return byte array
  603.      * @throws ZipException
  604.      */
  605.     private byte[] getLongByteFromIntByte(byte[] intByte) throws ZipException {
  606.         if (intByte == null) {
  607.             throw new ZipException("input parameter is null, cannot expand to 8 bytes");
  608.         }
  609.  
  610.         if (intByte.length != 4) {
  611.             throw new ZipException("invalid byte length, cannot expand to 8 bytes");
  612.         }
  613.  
  614.         byte[] longBuff = {intByte[0], intByte[1], intByte[2], intByte[3], 0, 0, 0, 0};
  615.         return longBuff;
  616.     }
  617. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement