Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      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 #ifndef ART_RUNTIME_ZIP_ARCHIVE_H_
     18 #define ART_RUNTIME_ZIP_ARCHIVE_H_
     19 
     20 #include <stdint.h>
     21 #include <zlib.h>
     22 
     23 #include "base/logging.h"
     24 #include "base/stringpiece.h"
     25 #include "base/unix_file/random_access_file.h"
     26 #include "globals.h"
     27 #include "mem_map.h"
     28 #include "os.h"
     29 #include "safe_map.h"
     30 #include "UniquePtr.h"
     31 
     32 namespace art {
     33 
     34 class ZipArchive;
     35 class MemMap;
     36 
     37 class ZipEntry {
     38  public:
     39   bool ExtractToFile(File& file);
     40   bool ExtractToMemory(uint8_t* begin, size_t size);
     41   MemMap* ExtractToMemMap(const char* entry_filename);
     42 
     43   uint32_t GetUncompressedLength();
     44   uint32_t GetCrc32();
     45 
     46  private:
     47   ZipEntry(const ZipArchive* zip_archive, const byte* ptr) : zip_archive_(zip_archive), ptr_(ptr) {}
     48 
     49   // Zip compression methods
     50   enum {
     51     kCompressStored     = 0,        // no compression
     52     kCompressDeflated   = 8,        // standard deflate
     53   };
     54 
     55   // kCompressStored, kCompressDeflated, ...
     56   uint16_t GetCompressionMethod();
     57 
     58   uint32_t GetCompressedLength();
     59 
     60   // returns -1 on error
     61   off64_t GetDataOffset();
     62 
     63   const ZipArchive* zip_archive_;
     64 
     65   // pointer to zip entry within central directory
     66   const byte* ptr_;
     67 
     68   friend class ZipArchive;
     69   DISALLOW_COPY_AND_ASSIGN(ZipEntry);
     70 };
     71 
     72 class ZipArchive {
     73  public:
     74   // Zip file constants.
     75   static const uint32_t kEOCDSignature      = 0x06054b50;
     76   static const int32_t kEOCDLen             = 22;
     77   static const int32_t kEOCDDiskNumber      =  4;              // number of the current disk
     78   static const int32_t kEOCDDiskNumberForCD =  6;              // disk number with the Central Directory
     79   static const int32_t kEOCDNumEntries      =  8;              // offset to #of entries in file
     80   static const int32_t kEOCDTotalNumEntries = 10;              // offset to total #of entries in spanned archives
     81   static const int32_t kEOCDSize            = 12;              // size of the central directory
     82   static const int32_t kEOCDFileOffset      = 16;              // offset to central directory
     83   static const int32_t kEOCDCommentSize     = 20;              // offset to the length of the file comment
     84 
     85   static const int32_t kMaxCommentLen = 65535;  // longest possible in uint16_t
     86   static const int32_t kMaxEOCDSearch = (kMaxCommentLen + kEOCDLen);
     87 
     88   static const uint32_t kLFHSignature = 0x04034b50;
     89   static const int32_t kLFHLen        = 30;  // excluding variable-len fields
     90   static const int32_t kLFHGPBFlags   = 6;   // offset to GPB flags
     91   static const int32_t kLFHNameLen    = 26;  // offset to filename length
     92   static const int32_t kLFHExtraLen   = 28;  // offset to extra length
     93 
     94   static const uint32_t kCDESignature   = 0x02014b50;
     95   static const int32_t kCDELen          = 46;  // excluding variable-len fields
     96   static const int32_t kCDEGPBFlags     = 8;   // offset to GPB flags
     97   static const int32_t kCDEMethod       = 10;  // offset to compression method
     98   static const int32_t kCDEModWhen      = 12;  // offset to modification timestamp
     99   static const int32_t kCDECRC          = 16;  // offset to entry CRC
    100   static const int32_t kCDECompLen      = 20;  // offset to compressed length
    101   static const int32_t kCDEUncompLen    = 24;  // offset to uncompressed length
    102   static const int32_t kCDENameLen      = 28;  // offset to filename length
    103   static const int32_t kCDEExtraLen     = 30;  // offset to extra length
    104   static const int32_t kCDECommentLen   = 32;  // offset to comment length
    105   static const int32_t kCDELocalOffset  = 42;  // offset to local hdr
    106 
    107   // General Purpose Bit Flag
    108   static const int32_t kGPFEncryptedFlag   = (1 << 0);
    109   static const int32_t kGPFUnsupportedMask = (kGPFEncryptedFlag);
    110 
    111   // return new ZipArchive instance on success, NULL on error.
    112   static ZipArchive* Open(const std::string& filename);
    113   static ZipArchive* OpenFromFd(int fd);
    114 
    115   ZipEntry* Find(const char* name) const;
    116 
    117   ~ZipArchive() {
    118     Close();
    119   }
    120 
    121  private:
    122   explicit ZipArchive(int fd) : fd_(fd), num_entries_(0), dir_offset_(0) {}
    123 
    124   bool MapCentralDirectory();
    125   bool Parse();
    126   void Close();
    127 
    128   int fd_;
    129   uint16_t num_entries_;
    130   off64_t dir_offset_;
    131   UniquePtr<MemMap> dir_map_;
    132   typedef SafeMap<StringPiece, const byte*> DirEntries;
    133   DirEntries dir_entries_;
    134 
    135   friend class ZipEntry;
    136 
    137   DISALLOW_COPY_AND_ASSIGN(ZipArchive);
    138 };
    139 
    140 }  // namespace art
    141 
    142 #endif  // ART_RUNTIME_ZIP_ARCHIVE_H_
    143