Package dpkt :: Module gzip
[hide private]
[frames] | no frames]

Source Code for Module dpkt.gzip

  1  # $Id: gzip.py 23 2006-11-08 15:45:33Z dugsong $ 
  2  # -*- coding: utf-8 -*- 
  3  """GNU zip.""" 
  4  from __future__ import print_function 
  5  from __future__ import absolute_import 
  6   
  7  import struct 
  8  import zlib 
  9  import binascii 
 10   
 11  from . import dpkt 
 12   
 13   
 14  # RFC 1952 
 15  GZIP_MAGIC = b'\x1f\x8b' 
 16   
 17  # Compression methods 
 18  GZIP_MSTORED = 0 
 19  GZIP_MCOMPRESS = 1 
 20  GZIP_MPACKED = 2 
 21  GZIP_MLZHED = 3 
 22  GZIP_MDEFLATE = 8 
 23   
 24  # Flags 
 25  GZIP_FTEXT = 0x01 
 26  GZIP_FHCRC = 0x02 
 27  GZIP_FEXTRA = 0x04 
 28  GZIP_FNAME = 0x08 
 29  GZIP_FCOMMENT = 0x10 
 30  GZIP_FENCRYPT = 0x20 
 31  GZIP_FRESERVED = 0xC0 
 32   
 33  # OS 
 34  GZIP_OS_MSDOS = 0 
 35  GZIP_OS_AMIGA = 1 
 36  GZIP_OS_VMS = 2 
 37  GZIP_OS_UNIX = 3 
 38  GZIP_OS_VMCMS = 4 
 39  GZIP_OS_ATARI = 5 
 40  GZIP_OS_OS2 = 6 
 41  GZIP_OS_MACOS = 7 
 42  GZIP_OS_ZSYSTEM = 8 
 43  GZIP_OS_CPM = 9 
 44  GZIP_OS_TOPS20 = 10 
 45  GZIP_OS_WIN32 = 11 
 46  GZIP_OS_QDOS = 12 
 47  GZIP_OS_RISCOS = 13 
 48  GZIP_OS_UNKNOWN = 255 
 49   
 50  GZIP_FENCRYPT_LEN = 12 
51 52 53 -class GzipExtra(dpkt.Packet):
54 __byte_order__ = '<' 55 __hdr__ = ( 56 ('id', '2s', ''), 57 ('len', 'H', 0) 58 )
59
60 61 -class Gzip(dpkt.Packet):
62 __byte_order__ = '<' 63 __hdr__ = ( 64 ('magic', '2s', GZIP_MAGIC), 65 ('method', 'B', GZIP_MDEFLATE), 66 ('flags', 'B', 0), 67 ('mtime', 'I', 0), 68 ('xflags', 'B', 0), 69 ('os', 'B', GZIP_OS_UNIX), 70 71 ('extra', '0s', ''), # XXX - GZIP_FEXTRA 72 ('filename', '0s', ''), # XXX - GZIP_FNAME 73 ('comment', '0s', '') # XXX - GZIP_FCOMMENT 74 ) 75
76 - def unpack(self, buf):
77 super(Gzip, self).unpack(buf) 78 if self.flags & GZIP_FEXTRA: 79 if len(self.data) < 2: 80 raise dpkt.NeedData('Gzip extra') 81 n = struct.unpack('<H', self.data[:2])[0] 82 if len(self.data) < 2 + n: 83 raise dpkt.NeedData('Gzip extra') 84 self.extra = GzipExtra(self.data[2:2 + n]) 85 self.data = self.data[2 + n:] 86 if self.flags & GZIP_FNAME: 87 n = self.data.find(b'\x00') 88 if n == -1: 89 raise dpkt.NeedData('Gzip end of file name not found') 90 self.filename = self.data[:n].decode('utf-8') 91 self.data = self.data[n + 1:] 92 if self.flags & GZIP_FCOMMENT: 93 n = self.data.find(b'\x00') 94 if n == -1: 95 raise dpkt.NeedData('Gzip end of comment not found') 96 self.comment = self.data[:n] 97 self.data = self.data[n + 1:] 98 if self.flags & GZIP_FENCRYPT: 99 if len(self.data) < GZIP_FENCRYPT_LEN: 100 raise dpkt.NeedData('Gzip encrypt') 101 self.data = self.data[GZIP_FENCRYPT_LEN:] # XXX - skip 102 if self.flags & GZIP_FHCRC: 103 if len(self.data) < 2: 104 raise dpkt.NeedData('Gzip hcrc') 105 self.data = self.data[2:] # XXX - skip
106
107 - def pack_hdr(self):
108 l = [] 109 if self.extra: 110 self.flags |= GZIP_FEXTRA 111 s = bytes(self.extra) 112 l.append(struct.pack('<H', len(s))) 113 l.append(s) 114 if self.filename: 115 self.flags |= GZIP_FNAME 116 l.append(self.filename) 117 l.append(b'\x00') 118 if self.comment: 119 self.flags |= GZIP_FCOMMENT 120 l.append(self.comment) 121 l.append(b'\x00') 122 l.insert(0, super(Gzip, self).pack_hdr()) 123 return b''.join(l)
124
125 - def compress(self):
126 """Compress self.data.""" 127 c = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS, 128 zlib.DEF_MEM_LEVEL, 0) 129 self.data = c.compress(self.data)
130
131 - def decompress(self):
132 """Return decompressed payload.""" 133 d = zlib.decompressobj(-zlib.MAX_WBITS) 134 return d.decompress(self.data)
135 136 137 _hexdecode = binascii.a2b_hex
138 139 -class TestGzip(object):
140 141 """This data is created with the gzip command line tool""" 142 143 @classmethod
144 - def setup_class(cls):
145 cls.data = _hexdecode(b'1F8B' # magic 146 b'080880C185560003' # header 147 b'68656C6C6F2E74787400' # filename 148 b'F348CDC9C95728CF2FCA4951E40200' # data 149 b'41E4A9B20D000000') # checksum 150 cls.p = Gzip(cls.data)
151
152 - def test_method(self):
153 assert (self.p.method == GZIP_MDEFLATE)
154
155 - def test_flags(self):
156 assert (self.p.flags == GZIP_FNAME)
157
158 - def test_mtime(self):
159 # Fri Jan 01 00:00:00 2016 UTC 160 assert (self.p.mtime == 0x5685c180)
161
162 - def test_xflags(self):
163 assert (self.p.xflags == 0)
164
165 - def test_os(self):
166 assert (self.p.os == GZIP_OS_UNIX)
167
168 - def test_filename(self):
169 assert (self.p.filename == "hello.txt") # always str (utf-8)
170
171 - def test_decompress(self):
172 assert (self.p.decompress() == b"Hello world!\n") # always bytes
173 174 175 if __name__ == '__main__': 176 import sys 177 178 gz = Gzip(open(sys.argv[1]).read()) 179 print(repr(gz), repr(gz.decompress())) 180