ZIP is a popular archive file format, introduced in 1989 by Phil Katz and originally implemented in PKZIP utility by PKWARE.
Thanks to solid support of it in most desktop environments and operating systems, and algorithms / specs availability in public domain, it quickly became tool of choice for implementing file containers.
For example, Java .jar files, OpenDocument, Office Open XML, EPUB files are actually ZIP archives.
This page hosts a formal specification of ZIP archive file using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.
import (
"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
"bytes"
"io"
)
/**
* ZIP is a popular archive file format, introduced in 1989 by Phil Katz
* and originally implemented in PKZIP utility by PKWARE.
*
* Thanks to solid support of it in most desktop environments and
* operating systems, and algorithms / specs availability in public
* domain, it quickly became tool of choice for implementing file
* containers.
*
* For example, Java .jar files, OpenDocument, Office Open XML, EPUB files
* are actually ZIP archives.
* @see <a href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT">Source</a>
* @see <a href="https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html">Source</a>
*/
type Zip_Compression int
const (
Zip_Compression__None Zip_Compression = 0
Zip_Compression__Shrunk Zip_Compression = 1
Zip_Compression__Reduced1 Zip_Compression = 2
Zip_Compression__Reduced2 Zip_Compression = 3
Zip_Compression__Reduced3 Zip_Compression = 4
Zip_Compression__Reduced4 Zip_Compression = 5
Zip_Compression__Imploded Zip_Compression = 6
Zip_Compression__Deflated Zip_Compression = 8
Zip_Compression__EnhancedDeflated Zip_Compression = 9
Zip_Compression__PkwareDclImploded Zip_Compression = 10
Zip_Compression__Bzip2 Zip_Compression = 12
Zip_Compression__Lzma Zip_Compression = 14
Zip_Compression__IbmTerse Zip_Compression = 18
Zip_Compression__IbmLz77Z Zip_Compression = 19
Zip_Compression__Zstandard Zip_Compression = 93
Zip_Compression__Mp3 Zip_Compression = 94
Zip_Compression__Xz Zip_Compression = 95
Zip_Compression__Jpeg Zip_Compression = 96
Zip_Compression__Wavpack Zip_Compression = 97
Zip_Compression__Ppmd Zip_Compression = 98
Zip_Compression__AexEncryptionMarker Zip_Compression = 99
)
var values_Zip_Compression = map[Zip_Compression]struct{}{0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 8: {}, 9: {}, 10: {}, 12: {}, 14: {}, 18: {}, 19: {}, 93: {}, 94: {}, 95: {}, 96: {}, 97: {}, 98: {}, 99: {}}
func (v Zip_Compression) isDefined() bool {
_, ok := values_Zip_Compression[v]
return ok
}
type Zip_ExtraCodes int
const (
Zip_ExtraCodes__Zip64 Zip_ExtraCodes = 1
Zip_ExtraCodes__AvInfo Zip_ExtraCodes = 7
Zip_ExtraCodes__Os2 Zip_ExtraCodes = 9
Zip_ExtraCodes__Ntfs Zip_ExtraCodes = 10
Zip_ExtraCodes__Openvms Zip_ExtraCodes = 12
Zip_ExtraCodes__PkwareUnix Zip_ExtraCodes = 13
Zip_ExtraCodes__FileStreamAndForkDescriptors Zip_ExtraCodes = 14
Zip_ExtraCodes__PatchDescriptor Zip_ExtraCodes = 15
Zip_ExtraCodes__Pkcs7 Zip_ExtraCodes = 20
Zip_ExtraCodes__X509CertIdAndSignatureForFile Zip_ExtraCodes = 21
Zip_ExtraCodes__X509CertIdForCentralDir Zip_ExtraCodes = 22
Zip_ExtraCodes__StrongEncryptionHeader Zip_ExtraCodes = 23
Zip_ExtraCodes__RecordManagementControls Zip_ExtraCodes = 24
Zip_ExtraCodes__Pkcs7EncRecipCertList Zip_ExtraCodes = 25
Zip_ExtraCodes__IbmS390Uncomp Zip_ExtraCodes = 101
Zip_ExtraCodes__IbmS390Comp Zip_ExtraCodes = 102
Zip_ExtraCodes__Poszip4690 Zip_ExtraCodes = 18064
Zip_ExtraCodes__ExtendedTimestamp Zip_ExtraCodes = 21589
Zip_ExtraCodes__Beos Zip_ExtraCodes = 25922
Zip_ExtraCodes__AsiUnix Zip_ExtraCodes = 30062
Zip_ExtraCodes__InfozipUnix Zip_ExtraCodes = 30805
Zip_ExtraCodes__InfozipUnixVarSize Zip_ExtraCodes = 30837
Zip_ExtraCodes__AexEncryption Zip_ExtraCodes = 39169
Zip_ExtraCodes__ApacheCommonsCompress Zip_ExtraCodes = 41246
Zip_ExtraCodes__MicrosoftOpenPackagingGrowthHint Zip_ExtraCodes = 41504
Zip_ExtraCodes__SmsQdos Zip_ExtraCodes = 64842
)
var values_Zip_ExtraCodes = map[Zip_ExtraCodes]struct{}{1: {}, 7: {}, 9: {}, 10: {}, 12: {}, 13: {}, 14: {}, 15: {}, 20: {}, 21: {}, 22: {}, 23: {}, 24: {}, 25: {}, 101: {}, 102: {}, 18064: {}, 21589: {}, 25922: {}, 30062: {}, 30805: {}, 30837: {}, 39169: {}, 41246: {}, 41504: {}, 64842: {}}
func (v Zip_ExtraCodes) isDefined() bool {
_, ok := values_Zip_ExtraCodes[v]
return ok
}
type Zip struct {
Sections []*Zip_PkSection
_io *kaitai.Stream
_root *Zip
_parent kaitai.Struct
}
func NewZip() *Zip {
return &Zip{
}
}
func (this Zip) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip) Read(io *kaitai.Stream, parent kaitai.Struct, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
for i := 0;; i++ {
tmp1, err := this._io.EOF()
if err != nil {
return err
}
if tmp1 {
break
}
tmp2 := NewZip_PkSection()
err = tmp2.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Sections = append(this.Sections, tmp2)
}
return err
}
/**
* @see <a href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT">- 4.3.12</a>
*/
type Zip_CentralDirEntry struct {
VersionMadeBy uint16
VersionNeededToExtract uint16
Flags uint16
CompressionMethod Zip_Compression
FileModTime *DosDatetime
Crc32 uint32
LenBodyCompressed uint32
LenBodyUncompressed uint32
LenFileName uint16
LenExtra uint16
LenComment uint16
DiskNumberStart uint16
IntFileAttr uint16
ExtFileAttr uint32
OfsLocalHeader int32
FileName string
Extra *Zip_Extras
Comment string
_io *kaitai.Stream
_root *Zip
_parent *Zip_PkSection
_raw_FileModTime []byte
_raw_Extra []byte
_f_localHeader bool
localHeader *Zip_PkSection
}
func NewZip_CentralDirEntry() *Zip_CentralDirEntry {
return &Zip_CentralDirEntry{
}
}
func (this Zip_CentralDirEntry) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_CentralDirEntry) Read(io *kaitai.Stream, parent *Zip_PkSection, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp3, err := this._io.ReadU2le()
if err != nil {
return err
}
this.VersionMadeBy = uint16(tmp3)
tmp4, err := this._io.ReadU2le()
if err != nil {
return err
}
this.VersionNeededToExtract = uint16(tmp4)
tmp5, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Flags = uint16(tmp5)
tmp6, err := this._io.ReadU2le()
if err != nil {
return err
}
this.CompressionMethod = Zip_Compression(tmp6)
tmp7, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp7 = tmp7
this._raw_FileModTime = tmp7
_io__raw_FileModTime := kaitai.NewStream(bytes.NewReader(this._raw_FileModTime))
tmp8 := NewDosDatetime()
err = tmp8.Read(_io__raw_FileModTime, nil, nil)
if err != nil {
return err
}
this.FileModTime = tmp8
tmp9, err := this._io.ReadU4le()
if err != nil {
return err
}
this.Crc32 = uint32(tmp9)
tmp10, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenBodyCompressed = uint32(tmp10)
tmp11, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenBodyUncompressed = uint32(tmp11)
tmp12, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenFileName = uint16(tmp12)
tmp13, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenExtra = uint16(tmp13)
tmp14, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenComment = uint16(tmp14)
tmp15, err := this._io.ReadU2le()
if err != nil {
return err
}
this.DiskNumberStart = uint16(tmp15)
tmp16, err := this._io.ReadU2le()
if err != nil {
return err
}
this.IntFileAttr = uint16(tmp16)
tmp17, err := this._io.ReadU4le()
if err != nil {
return err
}
this.ExtFileAttr = uint32(tmp17)
tmp18, err := this._io.ReadS4le()
if err != nil {
return err
}
this.OfsLocalHeader = int32(tmp18)
tmp19, err := this._io.ReadBytes(int(this.LenFileName))
if err != nil {
return err
}
tmp19 = tmp19
this.FileName = string(tmp19)
tmp20, err := this._io.ReadBytes(int(this.LenExtra))
if err != nil {
return err
}
tmp20 = tmp20
this._raw_Extra = tmp20
_io__raw_Extra := kaitai.NewStream(bytes.NewReader(this._raw_Extra))
tmp21 := NewZip_Extras()
err = tmp21.Read(_io__raw_Extra, this, this._root)
if err != nil {
return err
}
this.Extra = tmp21
tmp22, err := this._io.ReadBytes(int(this.LenComment))
if err != nil {
return err
}
tmp22 = tmp22
this.Comment = string(tmp22)
return err
}
func (this *Zip_CentralDirEntry) LocalHeader() (v *Zip_PkSection, err error) {
if (this._f_localHeader) {
return this.localHeader, nil
}
this._f_localHeader = true
_pos, err := this._io.Pos()
if err != nil {
return nil, err
}
_, err = this._io.Seek(int64(this.OfsLocalHeader), io.SeekStart)
if err != nil {
return nil, err
}
tmp23 := NewZip_PkSection()
err = tmp23.Read(this._io, this, this._root)
if err != nil {
return nil, err
}
this.localHeader = tmp23
_, err = this._io.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.localHeader, nil
}
type Zip_DataDescriptor struct {
Crc32 uint32
LenBodyCompressed uint32
LenBodyUncompressed uint32
_io *kaitai.Stream
_root *Zip
_parent *Zip_PkSection
}
func NewZip_DataDescriptor() *Zip_DataDescriptor {
return &Zip_DataDescriptor{
}
}
func (this Zip_DataDescriptor) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_DataDescriptor) Read(io *kaitai.Stream, parent *Zip_PkSection, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp24, err := this._io.ReadU4le()
if err != nil {
return err
}
this.Crc32 = uint32(tmp24)
tmp25, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenBodyCompressed = uint32(tmp25)
tmp26, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenBodyUncompressed = uint32(tmp26)
return err
}
type Zip_EndOfCentralDir struct {
DiskOfEndOfCentralDir uint16
DiskOfCentralDir uint16
NumCentralDirEntriesOnDisk uint16
NumCentralDirEntriesTotal uint16
LenCentralDir uint32
OfsCentralDir uint32
LenComment uint16
Comment string
_io *kaitai.Stream
_root *Zip
_parent *Zip_PkSection
}
func NewZip_EndOfCentralDir() *Zip_EndOfCentralDir {
return &Zip_EndOfCentralDir{
}
}
func (this Zip_EndOfCentralDir) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_EndOfCentralDir) Read(io *kaitai.Stream, parent *Zip_PkSection, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp27, err := this._io.ReadU2le()
if err != nil {
return err
}
this.DiskOfEndOfCentralDir = uint16(tmp27)
tmp28, err := this._io.ReadU2le()
if err != nil {
return err
}
this.DiskOfCentralDir = uint16(tmp28)
tmp29, err := this._io.ReadU2le()
if err != nil {
return err
}
this.NumCentralDirEntriesOnDisk = uint16(tmp29)
tmp30, err := this._io.ReadU2le()
if err != nil {
return err
}
this.NumCentralDirEntriesTotal = uint16(tmp30)
tmp31, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenCentralDir = uint32(tmp31)
tmp32, err := this._io.ReadU4le()
if err != nil {
return err
}
this.OfsCentralDir = uint32(tmp32)
tmp33, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenComment = uint16(tmp33)
tmp34, err := this._io.ReadBytes(int(this.LenComment))
if err != nil {
return err
}
tmp34 = tmp34
this.Comment = string(tmp34)
return err
}
type Zip_ExtraField struct {
Code Zip_ExtraCodes
LenBody uint16
Body interface{}
_io *kaitai.Stream
_root *Zip
_parent *Zip_Extras
_raw_Body []byte
}
func NewZip_ExtraField() *Zip_ExtraField {
return &Zip_ExtraField{
}
}
func (this Zip_ExtraField) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_ExtraField) Read(io *kaitai.Stream, parent *Zip_Extras, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp35, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Code = Zip_ExtraCodes(tmp35)
tmp36, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenBody = uint16(tmp36)
switch (this.Code) {
case Zip_ExtraCodes__ExtendedTimestamp:
tmp37, err := this._io.ReadBytes(int(this.LenBody))
if err != nil {
return err
}
tmp37 = tmp37
this._raw_Body = tmp37
_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
tmp38 := NewZip_ExtraField_ExtendedTimestamp()
err = tmp38.Read(_io__raw_Body, this, this._root)
if err != nil {
return err
}
this.Body = tmp38
case Zip_ExtraCodes__InfozipUnixVarSize:
tmp39, err := this._io.ReadBytes(int(this.LenBody))
if err != nil {
return err
}
tmp39 = tmp39
this._raw_Body = tmp39
_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
tmp40 := NewZip_ExtraField_InfozipUnixVarSize()
err = tmp40.Read(_io__raw_Body, this, this._root)
if err != nil {
return err
}
this.Body = tmp40
case Zip_ExtraCodes__Ntfs:
tmp41, err := this._io.ReadBytes(int(this.LenBody))
if err != nil {
return err
}
tmp41 = tmp41
this._raw_Body = tmp41
_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
tmp42 := NewZip_ExtraField_Ntfs()
err = tmp42.Read(_io__raw_Body, this, this._root)
if err != nil {
return err
}
this.Body = tmp42
default:
tmp43, err := this._io.ReadBytes(int(this.LenBody))
if err != nil {
return err
}
tmp43 = tmp43
this._raw_Body = tmp43
}
return err
}
/**
* @see <a href="https://github.com/LuaDist/zip/blob/b710806/proginfo/extrafld.txt#L817">Source</a>
*/
type Zip_ExtraField_ExtendedTimestamp struct {
Flags *Zip_ExtraField_ExtendedTimestamp_InfoFlags
ModTime uint32
AccessTime uint32
CreateTime uint32
_io *kaitai.Stream
_root *Zip
_parent *Zip_ExtraField
_raw_Flags []byte
}
func NewZip_ExtraField_ExtendedTimestamp() *Zip_ExtraField_ExtendedTimestamp {
return &Zip_ExtraField_ExtendedTimestamp{
}
}
func (this Zip_ExtraField_ExtendedTimestamp) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_ExtraField_ExtendedTimestamp) Read(io *kaitai.Stream, parent *Zip_ExtraField, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp44, err := this._io.ReadBytes(int(1))
if err != nil {
return err
}
tmp44 = tmp44
this._raw_Flags = tmp44
_io__raw_Flags := kaitai.NewStream(bytes.NewReader(this._raw_Flags))
tmp45 := NewZip_ExtraField_ExtendedTimestamp_InfoFlags()
err = tmp45.Read(_io__raw_Flags, this, this._root)
if err != nil {
return err
}
this.Flags = tmp45
if (this.Flags.HasModTime) {
tmp46, err := this._io.ReadU4le()
if err != nil {
return err
}
this.ModTime = uint32(tmp46)
}
if (this.Flags.HasAccessTime) {
tmp47, err := this._io.ReadU4le()
if err != nil {
return err
}
this.AccessTime = uint32(tmp47)
}
if (this.Flags.HasCreateTime) {
tmp48, err := this._io.ReadU4le()
if err != nil {
return err
}
this.CreateTime = uint32(tmp48)
}
return err
}
/**
* Unix timestamp
*/
/**
* Unix timestamp
*/
/**
* Unix timestamp
*/
type Zip_ExtraField_ExtendedTimestamp_InfoFlags struct {
HasModTime bool
HasAccessTime bool
HasCreateTime bool
Reserved uint64
_io *kaitai.Stream
_root *Zip
_parent *Zip_ExtraField_ExtendedTimestamp
}
func NewZip_ExtraField_ExtendedTimestamp_InfoFlags() *Zip_ExtraField_ExtendedTimestamp_InfoFlags {
return &Zip_ExtraField_ExtendedTimestamp_InfoFlags{
}
}
func (this Zip_ExtraField_ExtendedTimestamp_InfoFlags) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_ExtraField_ExtendedTimestamp_InfoFlags) Read(io *kaitai.Stream, parent *Zip_ExtraField_ExtendedTimestamp, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp49, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.HasModTime = tmp49 != 0
tmp50, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.HasAccessTime = tmp50 != 0
tmp51, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.HasCreateTime = tmp51 != 0
tmp52, err := this._io.ReadBitsIntLe(5)
if err != nil {
return err
}
this.Reserved = tmp52
return err
}
/**
* @see <a href="https://github.com/LuaDist/zip/blob/b710806/proginfo/extrafld.txt#L1339">Source</a>
*/
type Zip_ExtraField_InfozipUnixVarSize struct {
Version uint8
LenUid uint8
Uid []byte
LenGid uint8
Gid []byte
_io *kaitai.Stream
_root *Zip
_parent *Zip_ExtraField
}
func NewZip_ExtraField_InfozipUnixVarSize() *Zip_ExtraField_InfozipUnixVarSize {
return &Zip_ExtraField_InfozipUnixVarSize{
}
}
func (this Zip_ExtraField_InfozipUnixVarSize) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_ExtraField_InfozipUnixVarSize) Read(io *kaitai.Stream, parent *Zip_ExtraField, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp53, err := this._io.ReadU1()
if err != nil {
return err
}
this.Version = tmp53
tmp54, err := this._io.ReadU1()
if err != nil {
return err
}
this.LenUid = tmp54
tmp55, err := this._io.ReadBytes(int(this.LenUid))
if err != nil {
return err
}
tmp55 = tmp55
this.Uid = tmp55
tmp56, err := this._io.ReadU1()
if err != nil {
return err
}
this.LenGid = tmp56
tmp57, err := this._io.ReadBytes(int(this.LenGid))
if err != nil {
return err
}
tmp57 = tmp57
this.Gid = tmp57
return err
}
/**
* Version of this extra field, currently 1
*/
/**
* Size of UID field
*/
/**
* UID (User ID) for a file
*/
/**
* Size of GID field
*/
/**
* GID (Group ID) for a file
*/
/**
* @see <a href="https://github.com/LuaDist/zip/blob/b710806/proginfo/extrafld.txt#L191">Source</a>
*/
type Zip_ExtraField_Ntfs struct {
Reserved uint32
Attributes []*Zip_ExtraField_Ntfs_Attribute
_io *kaitai.Stream
_root *Zip
_parent *Zip_ExtraField
}
func NewZip_ExtraField_Ntfs() *Zip_ExtraField_Ntfs {
return &Zip_ExtraField_Ntfs{
}
}
func (this Zip_ExtraField_Ntfs) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_ExtraField_Ntfs) Read(io *kaitai.Stream, parent *Zip_ExtraField, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp58, err := this._io.ReadU4le()
if err != nil {
return err
}
this.Reserved = uint32(tmp58)
for i := 0;; i++ {
tmp59, err := this._io.EOF()
if err != nil {
return err
}
if tmp59 {
break
}
tmp60 := NewZip_ExtraField_Ntfs_Attribute()
err = tmp60.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Attributes = append(this.Attributes, tmp60)
}
return err
}
type Zip_ExtraField_Ntfs_Attribute struct {
Tag uint16
LenBody uint16
Body interface{}
_io *kaitai.Stream
_root *Zip
_parent *Zip_ExtraField_Ntfs
_raw_Body []byte
}
func NewZip_ExtraField_Ntfs_Attribute() *Zip_ExtraField_Ntfs_Attribute {
return &Zip_ExtraField_Ntfs_Attribute{
}
}
func (this Zip_ExtraField_Ntfs_Attribute) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_ExtraField_Ntfs_Attribute) Read(io *kaitai.Stream, parent *Zip_ExtraField_Ntfs, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp61, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Tag = uint16(tmp61)
tmp62, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenBody = uint16(tmp62)
switch (this.Tag) {
case 1:
tmp63, err := this._io.ReadBytes(int(this.LenBody))
if err != nil {
return err
}
tmp63 = tmp63
this._raw_Body = tmp63
_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
tmp64 := NewZip_ExtraField_Ntfs_Attribute1()
err = tmp64.Read(_io__raw_Body, this, this._root)
if err != nil {
return err
}
this.Body = tmp64
default:
tmp65, err := this._io.ReadBytes(int(this.LenBody))
if err != nil {
return err
}
tmp65 = tmp65
this._raw_Body = tmp65
}
return err
}
type Zip_ExtraField_Ntfs_Attribute1 struct {
LastModTime uint64
LastAccessTime uint64
CreationTime uint64
_io *kaitai.Stream
_root *Zip
_parent *Zip_ExtraField_Ntfs_Attribute
}
func NewZip_ExtraField_Ntfs_Attribute1() *Zip_ExtraField_Ntfs_Attribute1 {
return &Zip_ExtraField_Ntfs_Attribute1{
}
}
func (this Zip_ExtraField_Ntfs_Attribute1) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_ExtraField_Ntfs_Attribute1) Read(io *kaitai.Stream, parent *Zip_ExtraField_Ntfs_Attribute, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp66, err := this._io.ReadU8le()
if err != nil {
return err
}
this.LastModTime = uint64(tmp66)
tmp67, err := this._io.ReadU8le()
if err != nil {
return err
}
this.LastAccessTime = uint64(tmp67)
tmp68, err := this._io.ReadU8le()
if err != nil {
return err
}
this.CreationTime = uint64(tmp68)
return err
}
type Zip_Extras struct {
Entries []*Zip_ExtraField
_io *kaitai.Stream
_root *Zip
_parent kaitai.Struct
}
func NewZip_Extras() *Zip_Extras {
return &Zip_Extras{
}
}
func (this Zip_Extras) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_Extras) Read(io *kaitai.Stream, parent kaitai.Struct, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
for i := 0;; i++ {
tmp69, err := this._io.EOF()
if err != nil {
return err
}
if tmp69 {
break
}
tmp70 := NewZip_ExtraField()
err = tmp70.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Entries = append(this.Entries, tmp70)
}
return err
}
type Zip_LocalFile struct {
Header *Zip_LocalFileHeader
Body []byte
_io *kaitai.Stream
_root *Zip
_parent *Zip_PkSection
}
func NewZip_LocalFile() *Zip_LocalFile {
return &Zip_LocalFile{
}
}
func (this Zip_LocalFile) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_LocalFile) Read(io *kaitai.Stream, parent *Zip_PkSection, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp71 := NewZip_LocalFileHeader()
err = tmp71.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Header = tmp71
tmp72, err := this._io.ReadBytes(int(this.Header.LenBodyCompressed))
if err != nil {
return err
}
tmp72 = tmp72
this.Body = tmp72
return err
}
type Zip_LocalFileHeader struct {
Version uint16
Flags *Zip_LocalFileHeader_GpFlags
CompressionMethod Zip_Compression
FileModTime *DosDatetime
Crc32 uint32
LenBodyCompressed uint32
LenBodyUncompressed uint32
LenFileName uint16
LenExtra uint16
FileName string
Extra *Zip_Extras
_io *kaitai.Stream
_root *Zip
_parent *Zip_LocalFile
_raw_Flags []byte
_raw_FileModTime []byte
_raw_Extra []byte
}
func NewZip_LocalFileHeader() *Zip_LocalFileHeader {
return &Zip_LocalFileHeader{
}
}
func (this Zip_LocalFileHeader) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_LocalFileHeader) Read(io *kaitai.Stream, parent *Zip_LocalFile, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp73, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Version = uint16(tmp73)
tmp74, err := this._io.ReadBytes(int(2))
if err != nil {
return err
}
tmp74 = tmp74
this._raw_Flags = tmp74
_io__raw_Flags := kaitai.NewStream(bytes.NewReader(this._raw_Flags))
tmp75 := NewZip_LocalFileHeader_GpFlags()
err = tmp75.Read(_io__raw_Flags, this, this._root)
if err != nil {
return err
}
this.Flags = tmp75
tmp76, err := this._io.ReadU2le()
if err != nil {
return err
}
this.CompressionMethod = Zip_Compression(tmp76)
tmp77, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp77 = tmp77
this._raw_FileModTime = tmp77
_io__raw_FileModTime := kaitai.NewStream(bytes.NewReader(this._raw_FileModTime))
tmp78 := NewDosDatetime()
err = tmp78.Read(_io__raw_FileModTime, nil, nil)
if err != nil {
return err
}
this.FileModTime = tmp78
tmp79, err := this._io.ReadU4le()
if err != nil {
return err
}
this.Crc32 = uint32(tmp79)
tmp80, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenBodyCompressed = uint32(tmp80)
tmp81, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenBodyUncompressed = uint32(tmp81)
tmp82, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenFileName = uint16(tmp82)
tmp83, err := this._io.ReadU2le()
if err != nil {
return err
}
this.LenExtra = uint16(tmp83)
tmp84, err := this._io.ReadBytes(int(this.LenFileName))
if err != nil {
return err
}
tmp84 = tmp84
this.FileName = string(tmp84)
tmp85, err := this._io.ReadBytes(int(this.LenExtra))
if err != nil {
return err
}
tmp85 = tmp85
this._raw_Extra = tmp85
_io__raw_Extra := kaitai.NewStream(bytes.NewReader(this._raw_Extra))
tmp86 := NewZip_Extras()
err = tmp86.Read(_io__raw_Extra, this, this._root)
if err != nil {
return err
}
this.Extra = tmp86
return err
}
/**
* @see <a href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT">- 4.4.4</a>
* @see <a href="https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html">Local file headers</a>
*/
type Zip_LocalFileHeader_GpFlags_DeflateMode int
const (
Zip_LocalFileHeader_GpFlags_DeflateMode__Normal Zip_LocalFileHeader_GpFlags_DeflateMode = 0
Zip_LocalFileHeader_GpFlags_DeflateMode__Maximum Zip_LocalFileHeader_GpFlags_DeflateMode = 1
Zip_LocalFileHeader_GpFlags_DeflateMode__Fast Zip_LocalFileHeader_GpFlags_DeflateMode = 2
Zip_LocalFileHeader_GpFlags_DeflateMode__SuperFast Zip_LocalFileHeader_GpFlags_DeflateMode = 3
)
var values_Zip_LocalFileHeader_GpFlags_DeflateMode = map[Zip_LocalFileHeader_GpFlags_DeflateMode]struct{}{0: {}, 1: {}, 2: {}, 3: {}}
func (v Zip_LocalFileHeader_GpFlags_DeflateMode) isDefined() bool {
_, ok := values_Zip_LocalFileHeader_GpFlags_DeflateMode[v]
return ok
}
type Zip_LocalFileHeader_GpFlags struct {
FileEncrypted bool
CompOptionsRaw uint64
HasDataDescriptor bool
Reserved1 bool
CompPatchedData bool
StrongEncrypt bool
Reserved2 uint64
LangEncoding bool
Reserved3 bool
MaskHeaderValues bool
Reserved4 uint64
_io *kaitai.Stream
_root *Zip
_parent *Zip_LocalFileHeader
_f_deflatedMode bool
deflatedMode Zip_LocalFileHeader_GpFlags_DeflateMode
_f_implodedDictByteSize bool
implodedDictByteSize int
_f_implodedNumSfTrees bool
implodedNumSfTrees int8
_f_lzmaHasEosMarker bool
lzmaHasEosMarker bool
}
func NewZip_LocalFileHeader_GpFlags() *Zip_LocalFileHeader_GpFlags {
return &Zip_LocalFileHeader_GpFlags{
}
}
func (this Zip_LocalFileHeader_GpFlags) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_LocalFileHeader_GpFlags) Read(io *kaitai.Stream, parent *Zip_LocalFileHeader, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp87, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.FileEncrypted = tmp87 != 0
tmp88, err := this._io.ReadBitsIntLe(2)
if err != nil {
return err
}
this.CompOptionsRaw = tmp88
tmp89, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.HasDataDescriptor = tmp89 != 0
tmp90, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.Reserved1 = tmp90 != 0
tmp91, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.CompPatchedData = tmp91 != 0
tmp92, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.StrongEncrypt = tmp92 != 0
tmp93, err := this._io.ReadBitsIntLe(4)
if err != nil {
return err
}
this.Reserved2 = tmp93
tmp94, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.LangEncoding = tmp94 != 0
tmp95, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.Reserved3 = tmp95 != 0
tmp96, err := this._io.ReadBitsIntLe(1)
if err != nil {
return err
}
this.MaskHeaderValues = tmp96 != 0
tmp97, err := this._io.ReadBitsIntLe(2)
if err != nil {
return err
}
this.Reserved4 = tmp97
return err
}
func (this *Zip_LocalFileHeader_GpFlags) DeflatedMode() (v Zip_LocalFileHeader_GpFlags_DeflateMode, err error) {
if (this._f_deflatedMode) {
return this.deflatedMode, nil
}
this._f_deflatedMode = true
if ( ((this._parent.CompressionMethod == Zip_Compression__Deflated) || (this._parent.CompressionMethod == Zip_Compression__EnhancedDeflated)) ) {
this.deflatedMode = Zip_LocalFileHeader_GpFlags_DeflateMode(Zip_LocalFileHeader_GpFlags_DeflateMode(this.CompOptionsRaw))
}
return this.deflatedMode, nil
}
/**
* 8KiB or 4KiB in bytes
*/
func (this *Zip_LocalFileHeader_GpFlags) ImplodedDictByteSize() (v int, err error) {
if (this._f_implodedDictByteSize) {
return this.implodedDictByteSize, nil
}
this._f_implodedDictByteSize = true
if (this._parent.CompressionMethod == Zip_Compression__Imploded) {
var tmp98 int8;
if (this.CompOptionsRaw & 1 != 0) {
tmp98 = 8
} else {
tmp98 = 4
}
this.implodedDictByteSize = int(tmp98 * 1024)
}
return this.implodedDictByteSize, nil
}
func (this *Zip_LocalFileHeader_GpFlags) ImplodedNumSfTrees() (v int8, err error) {
if (this._f_implodedNumSfTrees) {
return this.implodedNumSfTrees, nil
}
this._f_implodedNumSfTrees = true
if (this._parent.CompressionMethod == Zip_Compression__Imploded) {
var tmp99 int8;
if (this.CompOptionsRaw & 2 != 0) {
tmp99 = 3
} else {
tmp99 = 2
}
this.implodedNumSfTrees = int8(tmp99)
}
return this.implodedNumSfTrees, nil
}
func (this *Zip_LocalFileHeader_GpFlags) LzmaHasEosMarker() (v bool, err error) {
if (this._f_lzmaHasEosMarker) {
return this.lzmaHasEosMarker, nil
}
this._f_lzmaHasEosMarker = true
if (this._parent.CompressionMethod == Zip_Compression__Lzma) {
this.lzmaHasEosMarker = bool(this.CompOptionsRaw & 1 != 0)
}
return this.lzmaHasEosMarker, nil
}
/**
* internal; access derived value instances instead
*/
type Zip_PkSection struct {
Magic []byte
SectionType uint16
Body kaitai.Struct
_io *kaitai.Stream
_root *Zip
_parent kaitai.Struct
}
func NewZip_PkSection() *Zip_PkSection {
return &Zip_PkSection{
}
}
func (this Zip_PkSection) IO_() *kaitai.Stream {
return this._io
}
func (this *Zip_PkSection) Read(io *kaitai.Stream, parent kaitai.Struct, root *Zip) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp100, err := this._io.ReadBytes(int(2))
if err != nil {
return err
}
tmp100 = tmp100
this.Magic = tmp100
if !(bytes.Equal(this.Magic, []uint8{80, 75})) {
return kaitai.NewValidationNotEqualError([]uint8{80, 75}, this.Magic, this._io, "/types/pk_section/seq/0")
}
tmp101, err := this._io.ReadU2le()
if err != nil {
return err
}
this.SectionType = uint16(tmp101)
switch (this.SectionType) {
case 1027:
tmp102 := NewZip_LocalFile()
err = tmp102.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp102
case 1541:
tmp103 := NewZip_EndOfCentralDir()
err = tmp103.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp103
case 2055:
tmp104 := NewZip_DataDescriptor()
err = tmp104.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp104
case 513:
tmp105 := NewZip_CentralDirEntry()
err = tmp105.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp105
}
return err
}