Browse code

7z support

aCaB authored on 2009/08/07 01:22:46
Showing 40 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,130 @@
0
+/*
1
+ *  Copyright (C) 2009 Sourcefire, Inc.
2
+ *
3
+ *  Authors: aCaB
4
+ *
5
+ *  This program is free software; you can redistribute it and/or modify
6
+ *  it under the terms of the GNU General Public License version 2 as
7
+ *  published by the Free Software Foundation.
8
+ *
9
+ *  This program is distributed in the hope that it will be useful,
10
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ *  GNU General Public License for more details.
13
+ *
14
+ *  You should have received a copy of the GNU General Public License
15
+ *  along with this program; if not, write to the Free Software
16
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ *  MA 02110-1301, USA.
18
+ */
19
+
20
+/* 7zip scanner */
21
+
22
+#if HAVE_CONFIG_H
23
+#include "clamav-config.h"
24
+#endif
25
+
26
+#include <stdio.h>
27
+#include <sys/types.h>
28
+#include <sys/stat.h>
29
+#include <fcntl.h>
30
+
31
+#include "others.h"
32
+#include "lzma_iface.h"
33
+#include "7z/7zFile.h"
34
+#include "7z/7zCrc.h"
35
+#include "7z/Archive/7z/7zIn.h"
36
+#include "7z/Archive/7z/7zExtract.h"
37
+
38
+#ifndef O_BINARY
39
+#define O_BINARY 0
40
+#endif
41
+
42
+static ISzAlloc allocImp = { __lzma_wrap_alloc, __lzma_wrap_free}, allocTempImp = { __lzma_wrap_alloc, __lzma_wrap_free};
43
+
44
+int cli_7unz (int fd, cli_ctx *ctx) {
45
+    CFileInStream archiveStream;
46
+    CLookToRead lookStream;
47
+    CSzArEx db;
48
+    UInt32 blockIndex = 0xFFFFFFFF;
49
+    char *buf = NULL;
50
+    size_t bufsz = 0;
51
+    UInt32 i;
52
+    int dupfd, ret = CL_CLEAN;
53
+
54
+    if((dupfd = dup(fd)) == -1) {
55
+	cli_errmsg("cli_7unz: dup() failed\n");
56
+	return CL_EDUP;
57
+    }
58
+    FileInStream_CreateVTable(&archiveStream);
59
+    archiveStream.file.file = fdopen(dupfd, "rb");
60
+    if(!archiveStream.file.file) {
61
+	cli_errmsg("cli_7unz: fdopen() failed\n");
62
+	return CL_EOPEN;
63
+    }
64
+    LookToRead_CreateVTable(&lookStream, False);
65
+    lookStream.realStream = &archiveStream.s;
66
+    LookToRead_Init(&lookStream);
67
+
68
+    CrcGenerateTable();
69
+
70
+    SzArEx_Init(&db);
71
+    if(SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) != SZ_OK) {
72
+	SzArEx_Free(&db, &allocImp);
73
+	cli_dbgmsg("cli_7unz: possibly damaged archive\n");
74
+	return CL_CLEAN;
75
+    }
76
+    for (i = 0; i < db.db.NumFiles; i++) {
77
+	CSzFileItem *f = db.db.Files + i;
78
+        size_t offset;
79
+        size_t usize;
80
+
81
+	if(f->IsDir || !f->Size) continue;
82
+	if(ctx->engine->maxfilesize && f->Size > ctx->engine->maxfilesize) {
83
+	    cli_dbgmsg("cli_7unz: skipping stream due to size limits (%lu vs %lu)\n", f->Size, ctx->engine->maxfilesize);
84
+	    continue;
85
+	}
86
+	cli_dbgmsg("cli_7unz: Extracting file %s\n", f->Name);
87
+	if(SzAr_Extract(&db, &lookStream.s, i, &blockIndex, &buf, &bufsz, &offset, &usize, &allocImp, &allocTempImp) == SZ_OK) {
88
+	    char *fname;
89
+	    int ofd;
90
+
91
+	    if(!usize) {
92
+		cli_dbgmsg("cli_7unz: stream uncompressed to an empty file\n");
93
+		continue;
94
+	    }
95
+	    if(!(fname = cli_gentemp(ctx->engine->tmpdir))) {
96
+		ret = CL_EMEM;
97
+		break;
98
+	    }
99
+	    if((ofd = open(fname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
100
+		cli_errmsg("cli_7unz: failed to create file %s\n", fname);
101
+		free(fname);
102
+		ret = CL_ECREAT;
103
+		break;
104
+	    }
105
+	    if(cli_writen(ofd, buf, usize) <= 0) {
106
+		close(ofd);
107
+		if(cli_unlink(fname)) ret = CL_EUNLINK;
108
+		else ret = CL_EWRITE;
109
+		free(fname);
110
+		break;
111
+	    }
112
+	    cli_dbgmsg("cli_7unz: extracted to %s\n", fname);
113
+	    lseek(ofd, 0, SEEK_SET);
114
+	    ret = cli_magic_scandesc(ofd, ctx);
115
+	    close(ofd);
116
+	    if(!ctx->engine->keeptmp)
117
+		if(cli_unlink(fname)) ret = CL_EUNLINK;
118
+	    free(fname);
119
+	    if(ret == CL_EUNLINK || ret == CL_VIRUS)
120
+		break;
121
+	} else {
122
+	    cli_dbgmsg("cli_7unz: decompression failed\n");
123
+	}
124
+    }
125
+    if(buf) free(buf);
126
+    SzArEx_Free(&db, &allocImp);
127
+    fclose(archiveStream.file.file);
128
+    return ret;
129
+}
0 130
new file mode 100644
... ...
@@ -0,0 +1,32 @@
0
+/*
1
+ *  Copyright (C) 2009 Sourcefire, Inc.
2
+ *
3
+ *  Authors: aCaB
4
+ *
5
+ *  This program is free software; you can redistribute it and/or modify
6
+ *  it under the terms of the GNU General Public License version 2 as
7
+ *  published by the Free Software Foundation.
8
+ *
9
+ *  This program is distributed in the hope that it will be useful,
10
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ *  GNU General Public License for more details.
13
+ *
14
+ *  You should have received a copy of the GNU General Public License
15
+ *  along with this program; if not, write to the Free Software
16
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ *  MA 02110-1301, USA.
18
+ */
19
+
20
+#ifndef __7Z_H
21
+#define __7Z_H
22
+
23
+#if HAVE_CONFIG_H
24
+#include "clamav-config.h"
25
+#endif
26
+
27
+#include "others.h"
28
+
29
+int cli_7unz (int, cli_ctx *);
30
+
31
+#endif
0 32
new file mode 100644
... ...
@@ -0,0 +1,36 @@
0
+/* 7zBuf.c -- Byte Buffer
1
+2008-03-28
2
+Igor Pavlov
3
+Public domain */
4
+
5
+#include "7zBuf.h"
6
+
7
+void Buf_Init(CBuf *p)
8
+{
9
+  p->data = 0;
10
+  p->size = 0;
11
+}
12
+
13
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
14
+{
15
+  p->size = 0;
16
+  if (size == 0)
17
+  {
18
+    p->data = 0;
19
+    return 1;
20
+  }
21
+  p->data = (Byte *)alloc->Alloc(alloc, size);
22
+  if (p->data != 0)
23
+  {
24
+    p->size = size;
25
+    return 1;
26
+  }
27
+  return 0;
28
+}
29
+
30
+void Buf_Free(CBuf *p, ISzAlloc *alloc)
31
+{
32
+  alloc->Free(alloc, p->data);
33
+  p->data = 0;
34
+  p->size = 0;
35
+}
0 36
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+/* 7zBuf.h -- Byte Buffer
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __7Z_BUF_H
4
+#define __7Z_BUF_H
5
+
6
+#include "Types.h"
7
+
8
+typedef struct
9
+{
10
+  Byte *data;
11
+  size_t size;
12
+} CBuf;
13
+
14
+void Buf_Init(CBuf *p);
15
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
16
+void Buf_Free(CBuf *p, ISzAlloc *alloc);
17
+
18
+typedef struct
19
+{
20
+  Byte *data;
21
+  size_t size;
22
+  size_t pos;
23
+} CDynBuf;
24
+
25
+void DynBuf_Construct(CDynBuf *p);
26
+void DynBuf_SeekToBeg(CDynBuf *p);
27
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
28
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
29
+
30
+#endif
0 31
new file mode 100644
... ...
@@ -0,0 +1,35 @@
0
+/* 7zCrc.c -- CRC32 calculation
1
+2008-08-05
2
+Igor Pavlov
3
+Public domain */
4
+
5
+#include "7zCrc.h"
6
+
7
+#define kCrcPoly 0xEDB88320
8
+UInt32 g_CrcTable[256];
9
+
10
+void MY_FAST_CALL CrcGenerateTable(void)
11
+{
12
+  UInt32 i;
13
+  for (i = 0; i < 256; i++)
14
+  {
15
+    UInt32 r = i;
16
+    int j;
17
+    for (j = 0; j < 8; j++)
18
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
19
+    g_CrcTable[i] = r;
20
+  }
21
+}
22
+
23
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
24
+{
25
+  const Byte *p = (const Byte *)data;
26
+  for (; size > 0 ; size--, p++)
27
+    v = CRC_UPDATE_BYTE(v, *p);
28
+  return v;
29
+}
30
+
31
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
32
+{
33
+  return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
34
+}
0 35
new file mode 100644
... ...
@@ -0,0 +1,24 @@
0
+/* 7zCrc.h -- CRC32 calculation
1
+2008-03-13
2
+Igor Pavlov
3
+Public domain */
4
+
5
+#ifndef __7Z_CRC_H
6
+#define __7Z_CRC_H
7
+
8
+#include <stddef.h>
9
+
10
+#include "Types.h"
11
+
12
+extern UInt32 g_CrcTable[];
13
+
14
+void MY_FAST_CALL CrcGenerateTable(void);
15
+
16
+#define CRC_INIT_VAL 0xFFFFFFFF
17
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
18
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
19
+
20
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
21
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
22
+
23
+#endif
0 24
new file mode 100644
... ...
@@ -0,0 +1,263 @@
0
+/* 7zFile.c -- File IO
1
+2008-11-22 : Igor Pavlov : Public domain */
2
+
3
+#include "7zFile.h"
4
+
5
+#ifndef USE_WINDOWS_FILE
6
+
7
+#include <errno.h>
8
+
9
+#endif
10
+
11
+#ifdef USE_WINDOWS_FILE
12
+
13
+/*
14
+   ReadFile and WriteFile functions in Windows have BUG:
15
+   If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
16
+   from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
17
+   (Insufficient system resources exist to complete the requested service).
18
+   Probably in some version of Windows there are problems with other sizes:
19
+   for 32 MB (maybe also for 16 MB).
20
+   And message can be "Network connection was lost"
21
+*/
22
+
23
+#define kChunkSizeMax (1 << 22)
24
+
25
+#endif
26
+
27
+void File_Construct(CSzFile *p)
28
+{
29
+  #ifdef USE_WINDOWS_FILE
30
+  p->handle = INVALID_HANDLE_VALUE;
31
+  #else
32
+  p->file = NULL;
33
+  #endif
34
+}
35
+
36
+static WRes File_Open(CSzFile *p, const char *name, int writeMode)
37
+{
38
+  #ifdef USE_WINDOWS_FILE
39
+  p->handle = CreateFileA(name,
40
+      writeMode ? GENERIC_WRITE : GENERIC_READ,
41
+      FILE_SHARE_READ, NULL,
42
+      writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
43
+      FILE_ATTRIBUTE_NORMAL, NULL);
44
+  return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
45
+  #else
46
+  p->file = fopen(name, writeMode ? "wb+" : "rb");
47
+  return (p->file != 0) ? 0 : errno;
48
+  #endif
49
+}
50
+
51
+WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
52
+WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
53
+
54
+WRes File_Close(CSzFile *p)
55
+{
56
+  #ifdef USE_WINDOWS_FILE
57
+  if (p->handle != INVALID_HANDLE_VALUE)
58
+  {
59
+    if (!CloseHandle(p->handle))
60
+      return GetLastError();
61
+    p->handle = INVALID_HANDLE_VALUE;
62
+  }
63
+  #else
64
+  if (p->file != NULL)
65
+  {
66
+    int res = fclose(p->file);
67
+    if (res != 0)
68
+      return res;
69
+    p->file = NULL;
70
+  }
71
+  #endif
72
+  return 0;
73
+}
74
+
75
+WRes File_Read(CSzFile *p, void *data, size_t *size)
76
+{
77
+  size_t originalSize = *size;
78
+  if (originalSize == 0)
79
+    return 0;
80
+
81
+  #ifdef USE_WINDOWS_FILE
82
+
83
+  *size = 0;
84
+  do
85
+  {
86
+    DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
87
+    DWORD processed = 0;
88
+    BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
89
+    data = (void *)((Byte *)data + processed);
90
+    originalSize -= processed;
91
+    *size += processed;
92
+    if (!res)
93
+      return GetLastError();
94
+    if (processed == 0)
95
+      break;
96
+  }
97
+  while (originalSize > 0);
98
+  return 0;
99
+
100
+  #else
101
+  
102
+  *size = fread(data, 1, originalSize, p->file);
103
+  if (*size == originalSize)
104
+    return 0;
105
+  return ferror(p->file);
106
+  
107
+  #endif
108
+}
109
+
110
+WRes File_Write(CSzFile *p, const void *data, size_t *size)
111
+{
112
+  size_t originalSize = *size;
113
+  if (originalSize == 0)
114
+    return 0;
115
+  
116
+  #ifdef USE_WINDOWS_FILE
117
+
118
+  *size = 0;
119
+  do
120
+  {
121
+    DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
122
+    DWORD processed = 0;
123
+    BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
124
+    data = (void *)((Byte *)data + processed);
125
+    originalSize -= processed;
126
+    *size += processed;
127
+    if (!res)
128
+      return GetLastError();
129
+    if (processed == 0)
130
+      break;
131
+  }
132
+  while (originalSize > 0);
133
+  return 0;
134
+
135
+  #else
136
+
137
+  *size = fwrite(data, 1, originalSize, p->file);
138
+  if (*size == originalSize)
139
+    return 0;
140
+  return ferror(p->file);
141
+  
142
+  #endif
143
+}
144
+
145
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
146
+{
147
+  #ifdef USE_WINDOWS_FILE
148
+
149
+  LARGE_INTEGER value;
150
+  DWORD moveMethod;
151
+  value.LowPart = (DWORD)*pos;
152
+  value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
153
+  switch (origin)
154
+  {
155
+    case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
156
+    case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
157
+    case SZ_SEEK_END: moveMethod = FILE_END; break;
158
+    default: return ERROR_INVALID_PARAMETER;
159
+  }
160
+  value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
161
+  if (value.LowPart == 0xFFFFFFFF)
162
+  {
163
+    WRes res = GetLastError();
164
+    if (res != NO_ERROR)
165
+      return res;
166
+  }
167
+  *pos = ((Int64)value.HighPart << 32) | value.LowPart;
168
+  return 0;
169
+
170
+  #else
171
+  
172
+  int moveMethod;
173
+  int res;
174
+  switch (origin)
175
+  {
176
+    case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
177
+    case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
178
+    case SZ_SEEK_END: moveMethod = SEEK_END; break;
179
+    default: return 1;
180
+  }
181
+  res = fseek(p->file, (long)*pos, moveMethod);
182
+  *pos = ftell(p->file);
183
+  return res;
184
+  
185
+  #endif
186
+}
187
+
188
+WRes File_GetLength(CSzFile *p, UInt64 *length)
189
+{
190
+  #ifdef USE_WINDOWS_FILE
191
+  
192
+  DWORD sizeHigh;
193
+  DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
194
+  if (sizeLow == 0xFFFFFFFF)
195
+  {
196
+    DWORD res = GetLastError();
197
+    if (res != NO_ERROR)
198
+      return res;
199
+  }
200
+  *length = (((UInt64)sizeHigh) << 32) + sizeLow;
201
+  return 0;
202
+  
203
+  #else
204
+  
205
+  long pos = ftell(p->file);
206
+  int res = fseek(p->file, 0, SEEK_END);
207
+  *length = ftell(p->file);
208
+  fseek(p->file, pos, SEEK_SET);
209
+  return res;
210
+  
211
+  #endif
212
+}
213
+
214
+
215
+/* ---------- FileSeqInStream ---------- */
216
+
217
+static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
218
+{
219
+  CFileSeqInStream *p = (CFileSeqInStream *)pp;
220
+  return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
221
+}
222
+
223
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
224
+{
225
+  p->s.Read = FileSeqInStream_Read;
226
+}
227
+
228
+
229
+/* ---------- FileInStream ---------- */
230
+
231
+static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
232
+{
233
+  CFileInStream *p = (CFileInStream *)pp;
234
+  return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
235
+}
236
+
237
+static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
238
+{
239
+  CFileInStream *p = (CFileInStream *)pp;
240
+  return File_Seek(&p->file, pos, origin);
241
+}
242
+
243
+void FileInStream_CreateVTable(CFileInStream *p)
244
+{
245
+  p->s.Read = FileInStream_Read;
246
+  p->s.Seek = FileInStream_Seek;
247
+}
248
+
249
+
250
+/* ---------- FileOutStream ---------- */
251
+
252
+static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
253
+{
254
+  CFileOutStream *p = (CFileOutStream *)pp;
255
+  File_Write(&p->file, data, &size);
256
+  return size;
257
+}
258
+
259
+void FileOutStream_CreateVTable(CFileOutStream *p)
260
+{
261
+  p->s.Write = FileOutStream_Write;
262
+}
0 263
new file mode 100644
... ...
@@ -0,0 +1,74 @@
0
+/* 7zFile.h -- File IO
1
+2008-11-22 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __7Z_FILE_H
4
+#define __7Z_FILE_H
5
+
6
+#ifdef _WIN32
7
+#define USE_WINDOWS_FILE
8
+#endif
9
+
10
+#ifdef USE_WINDOWS_FILE
11
+#include <windows.h>
12
+#else
13
+#include <stdio.h>
14
+#endif
15
+
16
+#include "Types.h"
17
+
18
+
19
+/* ---------- File ---------- */
20
+
21
+typedef struct
22
+{
23
+  #ifdef USE_WINDOWS_FILE
24
+  HANDLE handle;
25
+  #else
26
+  FILE *file;
27
+  #endif
28
+} CSzFile;
29
+
30
+void File_Construct(CSzFile *p);
31
+WRes InFile_Open(CSzFile *p, const char *name);
32
+WRes OutFile_Open(CSzFile *p, const char *name);
33
+WRes File_Close(CSzFile *p);
34
+
35
+/* reads max(*size, remain file's size) bytes */
36
+WRes File_Read(CSzFile *p, void *data, size_t *size);
37
+
38
+/* writes *size bytes */
39
+WRes File_Write(CSzFile *p, const void *data, size_t *size);
40
+
41
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
42
+WRes File_GetLength(CSzFile *p, UInt64 *length);
43
+
44
+
45
+/* ---------- FileInStream ---------- */
46
+
47
+typedef struct
48
+{
49
+  ISeqInStream s;
50
+  CSzFile file;
51
+} CFileSeqInStream;
52
+
53
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
54
+
55
+
56
+typedef struct
57
+{
58
+  ISeekInStream s;
59
+  CSzFile file;
60
+} CFileInStream;
61
+
62
+void FileInStream_CreateVTable(CFileInStream *p);
63
+
64
+
65
+typedef struct
66
+{
67
+  ISeqOutStream s;
68
+  CSzFile file;
69
+} CFileOutStream;
70
+
71
+void FileOutStream_CreateVTable(CFileOutStream *p);
72
+
73
+#endif
0 74
new file mode 100644
... ...
@@ -0,0 +1,169 @@
0
+/* 7zStream.c -- 7z Stream functions
1
+2008-11-23 : Igor Pavlov : Public domain */
2
+
3
+#include <string.h>
4
+
5
+#include "Types.h"
6
+
7
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
8
+{
9
+  while (size != 0)
10
+  {
11
+    size_t processed = size;
12
+    RINOK(stream->Read(stream, buf, &processed));
13
+    if (processed == 0)
14
+      return errorType;
15
+    buf = (void *)((Byte *)buf + processed);
16
+    size -= processed;
17
+  }
18
+  return SZ_OK;
19
+}
20
+
21
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
22
+{
23
+  return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
24
+}
25
+
26
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
27
+{
28
+  size_t processed = 1;
29
+  RINOK(stream->Read(stream, buf, &processed));
30
+  return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
31
+}
32
+
33
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
34
+{
35
+  Int64 t = offset;
36
+  return stream->Seek(stream, &t, SZ_SEEK_SET);
37
+}
38
+
39
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
40
+{
41
+  void *lookBuf;
42
+  if (*size == 0)
43
+    return SZ_OK;
44
+  RINOK(stream->Look(stream, &lookBuf, size));
45
+  memcpy(buf, lookBuf, *size);
46
+  return stream->Skip(stream, *size);
47
+}
48
+
49
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
50
+{
51
+  while (size != 0)
52
+  {
53
+    size_t processed = size;
54
+    RINOK(stream->Read(stream, buf, &processed));
55
+    if (processed == 0)
56
+      return errorType;
57
+    buf = (void *)((Byte *)buf + processed);
58
+    size -= processed;
59
+  }
60
+  return SZ_OK;
61
+}
62
+
63
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
64
+{
65
+  return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
66
+}
67
+
68
+static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
69
+{
70
+  SRes res = SZ_OK;
71
+  CLookToRead *p = (CLookToRead *)pp;
72
+  size_t size2 = p->size - p->pos;
73
+  if (size2 == 0 && *size > 0)
74
+  {
75
+    p->pos = 0;
76
+    size2 = LookToRead_BUF_SIZE;
77
+    res = p->realStream->Read(p->realStream, p->buf, &size2);
78
+    p->size = size2;
79
+  }
80
+  if (size2 < *size)
81
+    *size = size2;
82
+  *buf = p->buf + p->pos;
83
+  return res;
84
+}
85
+
86
+static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size)
87
+{
88
+  SRes res = SZ_OK;
89
+  CLookToRead *p = (CLookToRead *)pp;
90
+  size_t size2 = p->size - p->pos;
91
+  if (size2 == 0 && *size > 0)
92
+  {
93
+    p->pos = 0;
94
+    if (*size > LookToRead_BUF_SIZE)
95
+      *size = LookToRead_BUF_SIZE;
96
+    res = p->realStream->Read(p->realStream, p->buf, size);
97
+    size2 = p->size = *size;
98
+  }
99
+  if (size2 < *size)
100
+    *size = size2;
101
+  *buf = p->buf + p->pos;
102
+  return res;
103
+}
104
+
105
+static SRes LookToRead_Skip(void *pp, size_t offset)
106
+{
107
+  CLookToRead *p = (CLookToRead *)pp;
108
+  p->pos += offset;
109
+  return SZ_OK;
110
+}
111
+
112
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
113
+{
114
+  CLookToRead *p = (CLookToRead *)pp;
115
+  size_t rem = p->size - p->pos;
116
+  if (rem == 0)
117
+    return p->realStream->Read(p->realStream, buf, size);
118
+  if (rem > *size)
119
+    rem = *size;
120
+  memcpy(buf, p->buf + p->pos, rem);
121
+  p->pos += rem;
122
+  *size = rem;
123
+  return SZ_OK;
124
+}
125
+
126
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
127
+{
128
+  CLookToRead *p = (CLookToRead *)pp;
129
+  p->pos = p->size = 0;
130
+  return p->realStream->Seek(p->realStream, pos, origin);
131
+}
132
+
133
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
134
+{
135
+  p->s.Look = lookahead ?
136
+      LookToRead_Look_Lookahead :
137
+      LookToRead_Look_Exact;
138
+  p->s.Skip = LookToRead_Skip;
139
+  p->s.Read = LookToRead_Read;
140
+  p->s.Seek = LookToRead_Seek;
141
+}
142
+
143
+void LookToRead_Init(CLookToRead *p)
144
+{
145
+  p->pos = p->size = 0;
146
+}
147
+
148
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
149
+{
150
+  CSecToLook *p = (CSecToLook *)pp;
151
+  return LookInStream_LookRead(p->realStream, buf, size);
152
+}
153
+
154
+void SecToLook_CreateVTable(CSecToLook *p)
155
+{
156
+  p->s.Read = SecToLook_Read;
157
+}
158
+
159
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
160
+{
161
+  CSecToRead *p = (CSecToRead *)pp;
162
+  return p->realStream->Read(p->realStream, buf, size);
163
+}
164
+
165
+void SecToRead_CreateVTable(CSecToRead *p)
166
+{
167
+  p->s.Read = SecToRead_Read;
168
+}
0 169
new file mode 100644
... ...
@@ -0,0 +1,254 @@
0
+/* 7zDecode.c -- Decoding from 7z folder
1
+2008-11-23 : Igor Pavlov : Public domain */
2
+
3
+#include <string.h>
4
+
5
+#include "../../Bcj2.h"
6
+#include "../../Bra.h"
7
+#include "../../LzmaDec.h"
8
+#include "7zDecode.h"
9
+
10
+#define k_Copy 0
11
+#define k_LZMA 0x30101
12
+#define k_BCJ 0x03030103
13
+#define k_BCJ2 0x0303011B
14
+
15
+static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
16
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
17
+{
18
+  CLzmaDec state;
19
+  SRes res = SZ_OK;
20
+
21
+  LzmaDec_Construct(&state);
22
+  RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
23
+  state.dic = outBuffer;
24
+  state.dicBufSize = outSize;
25
+  LzmaDec_Init(&state);
26
+
27
+  for (;;)
28
+  {
29
+    Byte *inBuf = NULL;
30
+    size_t lookahead = (1 << 18);
31
+    if (lookahead > inSize)
32
+      lookahead = (size_t)inSize;
33
+    res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
34
+    if (res != SZ_OK)
35
+      break;
36
+
37
+    {
38
+      SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
39
+      ELzmaStatus status;
40
+      res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
41
+      lookahead -= inProcessed;
42
+      inSize -= inProcessed;
43
+      if (res != SZ_OK)
44
+        break;
45
+      if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
46
+      {
47
+        if (state.dicBufSize != outSize || lookahead != 0 ||
48
+            (status != LZMA_STATUS_FINISHED_WITH_MARK &&
49
+             status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
50
+          res = SZ_ERROR_DATA;
51
+        break;
52
+      }
53
+      res = inStream->Skip((void *)inStream, inProcessed);
54
+      if (res != SZ_OK)
55
+        break;
56
+    }
57
+  }
58
+
59
+  LzmaDec_FreeProbs(&state, allocMain);
60
+  return res;
61
+}
62
+
63
+static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
64
+{
65
+  while (inSize > 0)
66
+  {
67
+    void *inBuf;
68
+    size_t curSize = (1 << 18);
69
+    if (curSize > inSize)
70
+      curSize = (size_t)inSize;
71
+    RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
72
+    if (curSize == 0)
73
+      return SZ_ERROR_INPUT_EOF;
74
+    memcpy(outBuffer, inBuf, curSize);
75
+    outBuffer += curSize;
76
+    inSize -= curSize;
77
+    RINOK(inStream->Skip((void *)inStream, curSize));
78
+  }
79
+  return SZ_OK;
80
+}
81
+
82
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
83
+#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
84
+#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
85
+#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
86
+
87
+SRes CheckSupportedFolder(const CSzFolder *f)
88
+{
89
+  if (f->NumCoders < 1 || f->NumCoders > 4)
90
+    return SZ_ERROR_UNSUPPORTED;
91
+  if (IS_UNSUPPORTED_CODER(f->Coders[0]))
92
+    return SZ_ERROR_UNSUPPORTED;
93
+  if (f->NumCoders == 1)
94
+  {
95
+    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
96
+      return SZ_ERROR_UNSUPPORTED;
97
+    return SZ_OK;
98
+  }
99
+  if (f->NumCoders == 2)
100
+  {
101
+    if (IS_NO_BCJ(f->Coders[1]) ||
102
+        f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
103
+        f->NumBindPairs != 1 ||
104
+        f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
105
+      return SZ_ERROR_UNSUPPORTED;
106
+    return SZ_OK;
107
+  }
108
+  if (f->NumCoders == 4)
109
+  {
110
+    if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
111
+        IS_UNSUPPORTED_CODER(f->Coders[2]) ||
112
+        IS_NO_BCJ2(f->Coders[3]))
113
+      return SZ_ERROR_UNSUPPORTED;
114
+    if (f->NumPackStreams != 4 ||
115
+        f->PackStreams[0] != 2 ||
116
+        f->PackStreams[1] != 6 ||
117
+        f->PackStreams[2] != 1 ||
118
+        f->PackStreams[3] != 0 ||
119
+        f->NumBindPairs != 3 ||
120
+        f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
121
+        f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
122
+        f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
123
+      return SZ_ERROR_UNSUPPORTED;
124
+    return SZ_OK;
125
+  }
126
+  return SZ_ERROR_UNSUPPORTED;
127
+}
128
+
129
+UInt64 GetSum(const UInt64 *values, UInt32 index)
130
+{
131
+  UInt64 sum = 0;
132
+  UInt32 i;
133
+  for (i = 0; i < index; i++)
134
+    sum += values[i];
135
+  return sum;
136
+}
137
+
138
+SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
139
+    ILookInStream *inStream, UInt64 startPos,
140
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
141
+    Byte *tempBuf[])
142
+{
143
+  UInt32 ci;
144
+  SizeT tempSizes[3] = { 0, 0, 0};
145
+  SizeT tempSize3 = 0;
146
+  Byte *tempBuf3 = 0;
147
+
148
+  RINOK(CheckSupportedFolder(folder));
149
+
150
+  for (ci = 0; ci < folder->NumCoders; ci++)
151
+  {
152
+    CSzCoderInfo *coder = &folder->Coders[ci];
153
+
154
+    if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
155
+    {
156
+      UInt32 si = 0;
157
+      UInt64 offset;
158
+      UInt64 inSize;
159
+      Byte *outBufCur = outBuffer;
160
+      SizeT outSizeCur = outSize;
161
+      if (folder->NumCoders == 4)
162
+      {
163
+        UInt32 indices[] = { 3, 2, 0 };
164
+        UInt64 unpackSize = folder->UnpackSizes[ci];
165
+        si = indices[ci];
166
+        if (ci < 2)
167
+        {
168
+          Byte *temp;
169
+          outSizeCur = (SizeT)unpackSize;
170
+          if (outSizeCur != unpackSize)
171
+            return SZ_ERROR_MEM;
172
+          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
173
+          if (temp == 0 && outSizeCur != 0)
174
+            return SZ_ERROR_MEM;
175
+          outBufCur = tempBuf[1 - ci] = temp;
176
+          tempSizes[1 - ci] = outSizeCur;
177
+        }
178
+        else if (ci == 2)
179
+        {
180
+          if (unpackSize > outSize) /* check it */
181
+            return SZ_ERROR_PARAM;
182
+          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
183
+          tempSize3 = outSizeCur = (SizeT)unpackSize;
184
+        }
185
+        else
186
+          return SZ_ERROR_UNSUPPORTED;
187
+      }
188
+      offset = GetSum(packSizes, si);
189
+      inSize = packSizes[si];
190
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
191
+
192
+      if (coder->MethodID == k_Copy)
193
+      {
194
+        if (inSize != outSizeCur) /* check it */
195
+          return SZ_ERROR_DATA;
196
+        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
197
+      }
198
+      else
199
+      {
200
+        RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
201
+      }
202
+    }
203
+    else if (coder->MethodID == k_BCJ)
204
+    {
205
+      UInt32 state;
206
+      if (ci != 1)
207
+        return SZ_ERROR_UNSUPPORTED;
208
+      x86_Convert_Init(state);
209
+      x86_Convert(outBuffer, outSize, 0, &state, 0);
210
+    }
211
+    else if (coder->MethodID == k_BCJ2)
212
+    {
213
+      UInt64 offset = GetSum(packSizes, 1);
214
+      UInt64 s3Size = packSizes[1];
215
+      SRes res;
216
+      if (ci != 3)
217
+        return SZ_ERROR_UNSUPPORTED;
218
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
219
+      tempSizes[2] = (SizeT)s3Size;
220
+      if (tempSizes[2] != s3Size)
221
+        return SZ_ERROR_MEM;
222
+      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
223
+      if (tempBuf[2] == 0 && tempSizes[2] != 0)
224
+        return SZ_ERROR_MEM;
225
+      res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
226
+      RINOK(res)
227
+
228
+      res = Bcj2_Decode(
229
+          tempBuf3, tempSize3,
230
+          tempBuf[0], tempSizes[0],
231
+          tempBuf[1], tempSizes[1],
232
+          tempBuf[2], tempSizes[2],
233
+          outBuffer, outSize);
234
+      RINOK(res)
235
+    }
236
+    else
237
+      return SZ_ERROR_UNSUPPORTED;
238
+  }
239
+  return SZ_OK;
240
+}
241
+
242
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
243
+    ILookInStream *inStream, UInt64 startPos,
244
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
245
+{
246
+  Byte *tempBuf[3] = { 0, 0, 0};
247
+  int i;
248
+  SRes res = SzDecode2(packSizes, folder, inStream, startPos,
249
+      outBuffer, (SizeT)outSize, allocMain, tempBuf);
250
+  for (i = 0; i < 3; i++)
251
+    IAlloc_Free(allocMain, tempBuf[i]);
252
+  return res;
253
+}
0 254
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+/* 7zDecode.h -- Decoding from 7z folder
1
+2008-11-23 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __7Z_DECODE_H
4
+#define __7Z_DECODE_H
5
+
6
+#include "7zItem.h"
7
+
8
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
9
+    ILookInStream *stream, UInt64 startPos,
10
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
11
+
12
+#endif
0 13
new file mode 100755
... ...
@@ -0,0 +1,93 @@
0
+/* 7zExtract.c -- Extracting from 7z archive
1
+2008-11-23 : Igor Pavlov : Public domain */
2
+
3
+#include "../../7zCrc.h"
4
+#include "7zDecode.h"
5
+#include "7zExtract.h"
6
+
7
+SRes SzAr_Extract(
8
+    const CSzArEx *p,
9
+    ILookInStream *inStream,
10
+    UInt32 fileIndex,
11
+    UInt32 *blockIndex,
12
+    Byte **outBuffer,
13
+    size_t *outBufferSize,
14
+    size_t *offset,
15
+    size_t *outSizeProcessed,
16
+    ISzAlloc *allocMain,
17
+    ISzAlloc *allocTemp)
18
+{
19
+  UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
20
+  SRes res = SZ_OK;
21
+  *offset = 0;
22
+  *outSizeProcessed = 0;
23
+  if (folderIndex == (UInt32)-1)
24
+  {
25
+    IAlloc_Free(allocMain, *outBuffer);
26
+    *blockIndex = folderIndex;
27
+    *outBuffer = 0;
28
+    *outBufferSize = 0;
29
+    return SZ_OK;
30
+  }
31
+
32
+  if (*outBuffer == 0 || *blockIndex != folderIndex)
33
+  {
34
+    CSzFolder *folder = p->db.Folders + folderIndex;
35
+    UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
36
+    size_t unpackSize = (size_t)unpackSizeSpec;
37
+    UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
38
+
39
+    if (unpackSize != unpackSizeSpec)
40
+      return SZ_ERROR_MEM;
41
+    *blockIndex = folderIndex;
42
+    IAlloc_Free(allocMain, *outBuffer);
43
+    *outBuffer = 0;
44
+    
45
+    RINOK(LookInStream_SeekTo(inStream, startOffset));
46
+    
47
+    if (res == SZ_OK)
48
+    {
49
+      *outBufferSize = unpackSize;
50
+      if (unpackSize != 0)
51
+      {
52
+        *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
53
+        if (*outBuffer == 0)
54
+          res = SZ_ERROR_MEM;
55
+      }
56
+      if (res == SZ_OK)
57
+      {
58
+        res = SzDecode(p->db.PackSizes +
59
+          p->FolderStartPackStreamIndex[folderIndex], folder,
60
+          inStream, startOffset,
61
+          *outBuffer, unpackSize, allocTemp);
62
+        if (res == SZ_OK)
63
+        {
64
+          if (folder->UnpackCRCDefined)
65
+          {
66
+            if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
67
+              res = SZ_ERROR_CRC;
68
+          }
69
+        }
70
+      }
71
+    }
72
+  }
73
+  if (res == SZ_OK)
74
+  {
75
+    UInt32 i;
76
+    CSzFileItem *fileItem = p->db.Files + fileIndex;
77
+    *offset = 0;
78
+    for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
79
+      *offset += (UInt32)p->db.Files[i].Size;
80
+    *outSizeProcessed = (size_t)fileItem->Size;
81
+    if (*offset + *outSizeProcessed > *outBufferSize)
82
+      return SZ_ERROR_FAIL;
83
+    {
84
+      if (fileItem->FileCRCDefined)
85
+      {
86
+        if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
87
+          res = SZ_ERROR_CRC;
88
+      }
89
+    }
90
+  }
91
+  return res;
92
+}
0 93
new file mode 100755
... ...
@@ -0,0 +1,41 @@
0
+/* 7zExtract.h -- Extracting from 7z archive
1
+2008-11-23 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __7Z_EXTRACT_H
4
+#define __7Z_EXTRACT_H
5
+
6
+#include "7zIn.h"
7
+
8
+/*
9
+  SzExtract extracts file from archive
10
+
11
+  *outBuffer must be 0 before first call for each new archive.
12
+
13
+  Extracting cache:
14
+    If you need to decompress more than one file, you can send
15
+    these values from previous call:
16
+      *blockIndex,
17
+      *outBuffer,
18
+      *outBufferSize
19
+    You can consider "*outBuffer" as cache of solid block. If your archive is solid,
20
+    it will increase decompression speed.
21
+  
22
+    If you use external function, you can declare these 3 cache variables
23
+    (blockIndex, outBuffer, outBufferSize) as static in that external function.
24
+    
25
+    Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
26
+*/
27
+
28
+SRes SzAr_Extract(
29
+    const CSzArEx *db,
30
+    ILookInStream *inStream,
31
+    UInt32 fileIndex,         /* index of file */
32
+    UInt32 *blockIndex,       /* index of solid block */
33
+    Byte **outBuffer,         /* pointer to pointer to output buffer (allocated with allocMain) */
34
+    size_t *outBufferSize,    /* buffer size for output buffer */
35
+    size_t *offset,           /* offset of stream for required file in *outBuffer */
36
+    size_t *outSizeProcessed, /* size of file in *outBuffer */
37
+    ISzAlloc *allocMain,
38
+    ISzAlloc *allocTemp);
39
+
40
+#endif
0 41
new file mode 100644
... ...
@@ -0,0 +1,6 @@
0
+/*  7zHeader.c -- 7z Headers
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#include "7zHeader.h"
4
+
5
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
0 6
new file mode 100644
... ...
@@ -0,0 +1,57 @@
0
+/* 7zHeader.h -- 7z Headers
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __7Z_HEADER_H
4
+#define __7Z_HEADER_H
5
+
6
+#include "../../Types.h"
7
+
8
+#define k7zSignatureSize 6
9
+extern Byte k7zSignature[k7zSignatureSize];
10
+
11
+#define k7zMajorVersion 0
12
+
13
+#define k7zStartHeaderSize 0x20
14
+
15
+enum EIdEnum
16
+{
17
+  k7zIdEnd,
18
+    
19
+  k7zIdHeader,
20
+    
21
+  k7zIdArchiveProperties,
22
+    
23
+  k7zIdAdditionalStreamsInfo,
24
+  k7zIdMainStreamsInfo,
25
+  k7zIdFilesInfo,
26
+  
27
+  k7zIdPackInfo,
28
+  k7zIdUnpackInfo,
29
+  k7zIdSubStreamsInfo,
30
+  
31
+  k7zIdSize,
32
+  k7zIdCRC,
33
+  
34
+  k7zIdFolder,
35
+  
36
+  k7zIdCodersUnpackSize,
37
+  k7zIdNumUnpackStream,
38
+  
39
+  k7zIdEmptyStream,
40
+  k7zIdEmptyFile,
41
+  k7zIdAnti,
42
+  
43
+  k7zIdName,
44
+  k7zIdCTime,
45
+  k7zIdATime,
46
+  k7zIdMTime,
47
+  k7zIdWinAttributes,
48
+  k7zIdComment,
49
+  
50
+  k7zIdEncodedHeader,
51
+  
52
+  k7zIdStartPos,
53
+  k7zIdDummy
54
+};
55
+
56
+#endif
0 57
new file mode 100644
... ...
@@ -0,0 +1,1204 @@
0
+/* 7zIn.c -- 7z Input functions
1
+2008-12-31 : Igor Pavlov : Public domain */
2
+
3
+#include "../../7zCrc.h"
4
+#include "../../CpuArch.h"
5
+
6
+#include "7zDecode.h"
7
+#include "7zIn.h"
8
+
9
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
10
+
11
+#define NUM_FOLDER_CODERS_MAX 32
12
+#define NUM_CODER_STREAMS_MAX 32
13
+
14
+void SzArEx_Init(CSzArEx *p)
15
+{
16
+  SzAr_Init(&p->db);
17
+  p->FolderStartPackStreamIndex = 0;
18
+  p->PackStreamStartPositions = 0;
19
+  p->FolderStartFileIndex = 0;
20
+  p->FileIndexToFolderIndexMap = 0;
21
+}
22
+
23
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
24
+{
25
+  IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
26
+  IAlloc_Free(alloc, p->PackStreamStartPositions);
27
+  IAlloc_Free(alloc, p->FolderStartFileIndex);
28
+  IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
29
+  SzAr_Free(&p->db, alloc);
30
+  SzArEx_Init(p);
31
+}
32
+
33
+/*
34
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
35
+{
36
+  return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
37
+}
38
+
39
+UInt64 GetFilePackSize(int fileIndex) const
40
+{
41
+  int folderIndex = FileIndexToFolderIndexMap[fileIndex];
42
+  if (folderIndex >= 0)
43
+  {
44
+    const CSzFolder &folderInfo = Folders[folderIndex];
45
+    if (FolderStartFileIndex[folderIndex] == fileIndex)
46
+    return GetFolderFullPackSize(folderIndex);
47
+  }
48
+  return 0;
49
+}
50
+*/
51
+
52
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
53
+  if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
54
+
55
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
56
+{
57
+  UInt32 startPos = 0;
58
+  UInt64 startPosSize = 0;
59
+  UInt32 i;
60
+  UInt32 folderIndex = 0;
61
+  UInt32 indexInFolder = 0;
62
+  MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
63
+  for (i = 0; i < p->db.NumFolders; i++)
64
+  {
65
+    p->FolderStartPackStreamIndex[i] = startPos;
66
+    startPos += p->db.Folders[i].NumPackStreams;
67
+  }
68
+
69
+  MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
70
+
71
+  for (i = 0; i < p->db.NumPackStreams; i++)
72
+  {
73
+    p->PackStreamStartPositions[i] = startPosSize;
74
+    startPosSize += p->db.PackSizes[i];
75
+  }
76
+
77
+  MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
78
+  MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
79
+
80
+  for (i = 0; i < p->db.NumFiles; i++)
81
+  {
82
+    CSzFileItem *file = p->db.Files + i;
83
+    int emptyStream = !file->HasStream;
84
+    if (emptyStream && indexInFolder == 0)
85
+    {
86
+      p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
87
+      continue;
88
+    }
89
+    if (indexInFolder == 0)
90
+    {
91
+      /*
92
+      v3.13 incorrectly worked with empty folders
93
+      v4.07: Loop for skipping empty folders
94
+      */
95
+      for (;;)
96
+      {
97
+        if (folderIndex >= p->db.NumFolders)
98
+          return SZ_ERROR_ARCHIVE;
99
+        p->FolderStartFileIndex[folderIndex] = i;
100
+        if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
101
+          break;
102
+        folderIndex++;
103
+      }
104
+    }
105
+    p->FileIndexToFolderIndexMap[i] = folderIndex;
106
+    if (emptyStream)
107
+      continue;
108
+    indexInFolder++;
109
+    if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
110
+    {
111
+      folderIndex++;
112
+      indexInFolder = 0;
113
+    }
114
+  }
115
+  return SZ_OK;
116
+}
117
+
118
+
119
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
120
+{
121
+  return p->dataPos +
122
+    p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
123
+}
124
+
125
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
126
+{
127
+  UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
128
+  CSzFolder *folder = p->db.Folders + folderIndex;
129
+  UInt64 size = 0;
130
+  UInt32 i;
131
+  for (i = 0; i < folder->NumPackStreams; i++)
132
+  {
133
+    UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
134
+    if (t < size) /* check it */
135
+      return SZ_ERROR_FAIL;
136
+    size = t;
137
+  }
138
+  *resSize = size;
139
+  return SZ_OK;
140
+}
141
+
142
+
143
+/*
144
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
145
+    CObjectVector<CSzFileItem> &files, UInt64 type)
146
+{
147
+  CBoolVector boolVector;
148
+  RINOK(ReadBoolVector2(files.Size(), boolVector))
149
+
150
+  CStreamSwitch streamSwitch;
151
+  RINOK(streamSwitch.Set(this, &dataVector));
152
+
153
+  for (int i = 0; i < files.Size(); i++)
154
+  {
155
+    CSzFileItem &file = files[i];
156
+    CArchiveFileTime fileTime;
157
+    bool defined = boolVector[i];
158
+    if (defined)
159
+    {
160
+      UInt32 low, high;
161
+      RINOK(SzReadUInt32(low));
162
+      RINOK(SzReadUInt32(high));
163
+      fileTime.dwLowDateTime = low;
164
+      fileTime.dwHighDateTime = high;
165
+    }
166
+    switch(type)
167
+    {
168
+      case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
169
+      case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
170
+      case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
171
+    }
172
+  }
173
+  return SZ_OK;
174
+}
175
+*/
176
+
177
+static int TestSignatureCandidate(Byte *testBytes)
178
+{
179
+  size_t i;
180
+  for (i = 0; i < k7zSignatureSize; i++)
181
+    if (testBytes[i] != k7zSignature[i])
182
+      return 0;
183
+  return 1;
184
+}
185
+
186
+typedef struct _CSzState
187
+{
188
+  Byte *Data;
189
+  size_t Size;
190
+}CSzData;
191
+
192
+static SRes SzReadByte(CSzData *sd, Byte *b)
193
+{
194
+  if (sd->Size == 0)
195
+    return SZ_ERROR_ARCHIVE;
196
+  sd->Size--;
197
+  *b = *sd->Data++;
198
+  return SZ_OK;
199
+}
200
+
201
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
202
+{
203
+  size_t i;
204
+  for (i = 0; i < size; i++)
205
+  {
206
+    RINOK(SzReadByte(sd, data + i));
207
+  }
208
+  return SZ_OK;
209
+}
210
+
211
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value)
212
+{
213
+  int i;
214
+  *value = 0;
215
+  for (i = 0; i < 4; i++)
216
+  {
217
+    Byte b;
218
+    RINOK(SzReadByte(sd, &b));
219
+    *value |= ((UInt32)(b) << (8 * i));
220
+  }
221
+  return SZ_OK;
222
+}
223
+
224
+static SRes SzReadNumber(CSzData *sd, UInt64 *value)
225
+{
226
+  Byte firstByte;
227
+  Byte mask = 0x80;
228
+  int i;
229
+  RINOK(SzReadByte(sd, &firstByte));
230
+  *value = 0;
231
+  for (i = 0; i < 8; i++)
232
+  {
233
+    Byte b;
234
+    if ((firstByte & mask) == 0)
235
+    {
236
+      UInt64 highPart = firstByte & (mask - 1);
237
+      *value += (highPart << (8 * i));
238
+      return SZ_OK;
239
+    }
240
+    RINOK(SzReadByte(sd, &b));
241
+    *value |= ((UInt64)b << (8 * i));
242
+    mask >>= 1;
243
+  }
244
+  return SZ_OK;
245
+}
246
+
247
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
248
+{
249
+  UInt64 value64;
250
+  RINOK(SzReadNumber(sd, &value64));
251
+  if (value64 >= 0x80000000)
252
+    return SZ_ERROR_UNSUPPORTED;
253
+  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
254
+    return SZ_ERROR_UNSUPPORTED;
255
+  *value = (UInt32)value64;
256
+  return SZ_OK;
257
+}
258
+
259
+static SRes SzReadID(CSzData *sd, UInt64 *value)
260
+{
261
+  return SzReadNumber(sd, value);
262
+}
263
+
264
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
265
+{
266
+  if (size > sd->Size)
267
+    return SZ_ERROR_ARCHIVE;
268
+  sd->Size -= (size_t)size;
269
+  sd->Data += (size_t)size;
270
+  return SZ_OK;
271
+}
272
+
273
+static SRes SzSkeepData(CSzData *sd)
274
+{
275
+  UInt64 size;
276
+  RINOK(SzReadNumber(sd, &size));
277
+  return SzSkeepDataSize(sd, size);
278
+}
279
+
280
+static SRes SzReadArchiveProperties(CSzData *sd)
281
+{
282
+  for (;;)
283
+  {
284
+    UInt64 type;
285
+    RINOK(SzReadID(sd, &type));
286
+    if (type == k7zIdEnd)
287
+      break;
288
+    SzSkeepData(sd);
289
+  }
290
+  return SZ_OK;
291
+}
292
+
293
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
294
+{
295
+  for (;;)
296
+  {
297
+    UInt64 type;
298
+    RINOK(SzReadID(sd, &type));
299
+    if (type == attribute)
300
+      return SZ_OK;
301
+    if (type == k7zIdEnd)
302
+      return SZ_ERROR_ARCHIVE;
303
+    RINOK(SzSkeepData(sd));
304
+  }
305
+}
306
+
307
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
308
+{
309
+  Byte b = 0;
310
+  Byte mask = 0;
311
+  size_t i;
312
+  MY_ALLOC(Byte, *v, numItems, alloc);
313
+  for (i = 0; i < numItems; i++)
314
+  {
315
+    if (mask == 0)
316
+    {
317
+      RINOK(SzReadByte(sd, &b));
318
+      mask = 0x80;
319
+    }
320
+    (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
321
+    mask >>= 1;
322
+  }
323
+  return SZ_OK;
324
+}
325
+
326
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
327
+{
328
+  Byte allAreDefined;
329
+  size_t i;
330
+  RINOK(SzReadByte(sd, &allAreDefined));
331
+  if (allAreDefined == 0)
332
+    return SzReadBoolVector(sd, numItems, v, alloc);
333
+  MY_ALLOC(Byte, *v, numItems, alloc);
334
+  for (i = 0; i < numItems; i++)
335
+    (*v)[i] = 1;
336
+  return SZ_OK;
337
+}
338
+
339
+static SRes SzReadHashDigests(
340
+    CSzData *sd,
341
+    size_t numItems,
342
+    Byte **digestsDefined,
343
+    UInt32 **digests,
344
+    ISzAlloc *alloc)
345
+{
346
+  size_t i;
347
+  RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
348
+  MY_ALLOC(UInt32, *digests, numItems, alloc);
349
+  for (i = 0; i < numItems; i++)
350
+    if ((*digestsDefined)[i])
351
+    {
352
+      RINOK(SzReadUInt32(sd, (*digests) + i));
353
+    }
354
+  return SZ_OK;
355
+}
356
+
357
+static SRes SzReadPackInfo(
358
+    CSzData *sd,
359
+    UInt64 *dataOffset,
360
+    UInt32 *numPackStreams,
361
+    UInt64 **packSizes,
362
+    Byte **packCRCsDefined,
363
+    UInt32 **packCRCs,
364
+    ISzAlloc *alloc)
365
+{
366
+  UInt32 i;
367
+  RINOK(SzReadNumber(sd, dataOffset));
368
+  RINOK(SzReadNumber32(sd, numPackStreams));
369
+
370
+  RINOK(SzWaitAttribute(sd, k7zIdSize));
371
+
372
+  MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
373
+
374
+  for (i = 0; i < *numPackStreams; i++)
375
+  {
376
+    RINOK(SzReadNumber(sd, (*packSizes) + i));
377
+  }
378
+
379
+  for (;;)
380
+  {
381
+    UInt64 type;
382
+    RINOK(SzReadID(sd, &type));
383
+    if (type == k7zIdEnd)
384
+      break;
385
+    if (type == k7zIdCRC)
386
+    {
387
+      RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
388
+      continue;
389
+    }
390
+    RINOK(SzSkeepData(sd));
391
+  }
392
+  if (*packCRCsDefined == 0)
393
+  {
394
+    MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
395
+    MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
396
+    for (i = 0; i < *numPackStreams; i++)
397
+    {
398
+      (*packCRCsDefined)[i] = 0;
399
+      (*packCRCs)[i] = 0;
400
+    }
401
+  }
402
+  return SZ_OK;
403
+}
404
+
405
+static SRes SzReadSwitch(CSzData *sd)
406
+{
407
+  Byte external;
408
+  RINOK(SzReadByte(sd, &external));
409
+  return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
410
+}
411
+
412
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
413
+{
414
+  UInt32 numCoders, numBindPairs, numPackStreams, i;
415
+  UInt32 numInStreams = 0, numOutStreams = 0;
416
+  
417
+  RINOK(SzReadNumber32(sd, &numCoders));
418
+  if (numCoders > NUM_FOLDER_CODERS_MAX)
419
+    return SZ_ERROR_UNSUPPORTED;
420
+  folder->NumCoders = numCoders;
421
+  
422
+  MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
423
+
424
+  for (i = 0; i < numCoders; i++)
425
+    SzCoderInfo_Init(folder->Coders + i);
426
+
427
+  for (i = 0; i < numCoders; i++)
428
+  {
429
+    Byte mainByte;
430
+    CSzCoderInfo *coder = folder->Coders + i;
431
+    {
432
+      unsigned idSize, j;
433
+      Byte longID[15];
434
+      RINOK(SzReadByte(sd, &mainByte));
435
+      idSize = (unsigned)(mainByte & 0xF);
436
+      RINOK(SzReadBytes(sd, longID, idSize));
437
+      if (idSize > sizeof(coder->MethodID))
438
+        return SZ_ERROR_UNSUPPORTED;
439
+      coder->MethodID = 0;
440
+      for (j = 0; j < idSize; j++)
441
+        coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
442
+
443
+      if ((mainByte & 0x10) != 0)
444
+      {
445
+        RINOK(SzReadNumber32(sd, &coder->NumInStreams));
446
+        RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
447
+        if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
448
+            coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
449
+          return SZ_ERROR_UNSUPPORTED;
450
+      }
451
+      else
452
+      {
453
+        coder->NumInStreams = 1;
454
+        coder->NumOutStreams = 1;
455
+      }
456
+      if ((mainByte & 0x20) != 0)
457
+      {
458
+        UInt64 propertiesSize = 0;
459
+        RINOK(SzReadNumber(sd, &propertiesSize));
460
+        if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
461
+          return SZ_ERROR_MEM;
462
+        RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
463
+      }
464
+    }
465
+    while ((mainByte & 0x80) != 0)
466
+    {
467
+      RINOK(SzReadByte(sd, &mainByte));
468
+      RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
469
+      if ((mainByte & 0x10) != 0)
470
+      {
471
+        UInt32 n;
472
+        RINOK(SzReadNumber32(sd, &n));
473
+        RINOK(SzReadNumber32(sd, &n));
474
+      }
475
+      if ((mainByte & 0x20) != 0)
476
+      {
477
+        UInt64 propertiesSize = 0;
478
+        RINOK(SzReadNumber(sd, &propertiesSize));
479
+        RINOK(SzSkeepDataSize(sd, propertiesSize));
480
+      }
481
+    }
482
+    numInStreams += coder->NumInStreams;
483
+    numOutStreams += coder->NumOutStreams;
484
+  }
485
+
486
+  if (numOutStreams == 0)
487
+    return SZ_ERROR_UNSUPPORTED;
488
+
489
+  folder->NumBindPairs = numBindPairs = numOutStreams - 1;
490
+  MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
491
+
492
+  for (i = 0; i < numBindPairs; i++)
493
+  {
494
+    CBindPair *bp = folder->BindPairs + i;
495
+    RINOK(SzReadNumber32(sd, &bp->InIndex));
496
+    RINOK(SzReadNumber32(sd, &bp->OutIndex));
497
+  }
498
+
499
+  if (numInStreams < numBindPairs)
500
+    return SZ_ERROR_UNSUPPORTED;
501
+
502
+  folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
503
+  MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
504
+
505
+  if (numPackStreams == 1)
506
+  {
507
+    for (i = 0; i < numInStreams ; i++)
508
+      if (SzFolder_FindBindPairForInStream(folder, i) < 0)
509
+        break;
510
+    if (i == numInStreams)
511
+      return SZ_ERROR_UNSUPPORTED;
512
+    folder->PackStreams[0] = i;
513
+  }
514
+  else
515
+    for (i = 0; i < numPackStreams; i++)
516
+    {
517
+      RINOK(SzReadNumber32(sd, folder->PackStreams + i));
518
+    }
519
+  return SZ_OK;
520
+}
521
+
522
+static SRes SzReadUnpackInfo(
523
+    CSzData *sd,
524
+    UInt32 *numFolders,
525
+    CSzFolder **folders,  /* for alloc */
526
+    ISzAlloc *alloc,
527
+    ISzAlloc *allocTemp)
528
+{
529
+  UInt32 i;
530
+  RINOK(SzWaitAttribute(sd, k7zIdFolder));
531
+  RINOK(SzReadNumber32(sd, numFolders));
532
+  {
533
+    RINOK(SzReadSwitch(sd));
534
+
535
+    MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
536
+
537
+    for (i = 0; i < *numFolders; i++)
538
+      SzFolder_Init((*folders) + i);
539
+
540
+    for (i = 0; i < *numFolders; i++)
541
+    {
542
+      RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
543
+    }
544
+  }
545
+
546
+  RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
547
+
548
+  for (i = 0; i < *numFolders; i++)
549
+  {
550
+    UInt32 j;
551
+    CSzFolder *folder = (*folders) + i;
552
+    UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
553
+
554
+    MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
555
+
556
+    for (j = 0; j < numOutStreams; j++)
557
+    {
558
+      RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
559
+    }
560
+  }
561
+
562
+  for (;;)
563
+  {
564
+    UInt64 type;
565
+    RINOK(SzReadID(sd, &type));
566
+    if (type == k7zIdEnd)
567
+      return SZ_OK;
568
+    if (type == k7zIdCRC)
569
+    {
570
+      SRes res;
571
+      Byte *crcsDefined = 0;
572
+      UInt32 *crcs = 0;
573
+      res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
574
+      if (res == SZ_OK)
575
+      {
576
+        for (i = 0; i < *numFolders; i++)
577
+        {
578
+          CSzFolder *folder = (*folders) + i;
579
+          folder->UnpackCRCDefined = crcsDefined[i];
580
+          folder->UnpackCRC = crcs[i];
581
+        }
582
+      }
583
+      IAlloc_Free(allocTemp, crcs);
584
+      IAlloc_Free(allocTemp, crcsDefined);
585
+      RINOK(res);
586
+      continue;
587
+    }
588
+    RINOK(SzSkeepData(sd));
589
+  }
590
+}
591
+
592
+static SRes SzReadSubStreamsInfo(
593
+    CSzData *sd,
594
+    UInt32 numFolders,
595
+    CSzFolder *folders,
596
+    UInt32 *numUnpackStreams,
597
+    UInt64 **unpackSizes,
598
+    Byte **digestsDefined,
599
+    UInt32 **digests,
600
+    ISzAlloc *allocTemp)
601
+{
602
+  UInt64 type = 0;
603
+  UInt32 i;
604
+  UInt32 si = 0;
605
+  UInt32 numDigests = 0;
606
+
607
+  for (i = 0; i < numFolders; i++)
608
+    folders[i].NumUnpackStreams = 1;
609
+  *numUnpackStreams = numFolders;
610
+
611
+  for (;;)
612
+  {
613
+    RINOK(SzReadID(sd, &type));
614
+    if (type == k7zIdNumUnpackStream)
615
+    {
616
+      *numUnpackStreams = 0;
617
+      for (i = 0; i < numFolders; i++)
618
+      {
619
+        UInt32 numStreams;
620
+        RINOK(SzReadNumber32(sd, &numStreams));
621
+        folders[i].NumUnpackStreams = numStreams;
622
+        *numUnpackStreams += numStreams;
623
+      }
624
+      continue;
625
+    }
626
+    if (type == k7zIdCRC || type == k7zIdSize)
627
+      break;
628
+    if (type == k7zIdEnd)
629
+      break;
630
+    RINOK(SzSkeepData(sd));
631
+  }
632
+
633
+  if (*numUnpackStreams == 0)
634
+  {
635
+    *unpackSizes = 0;
636
+    *digestsDefined = 0;
637
+    *digests = 0;
638
+  }
639
+  else
640
+  {
641
+    *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
642
+    RINOM(*unpackSizes);
643
+    *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
644
+    RINOM(*digestsDefined);
645
+    *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
646
+    RINOM(*digests);
647
+  }
648
+
649
+  for (i = 0; i < numFolders; i++)
650
+  {
651
+    /*
652
+    v3.13 incorrectly worked with empty folders
653
+    v4.07: we check that folder is empty
654
+    */
655
+    UInt64 sum = 0;
656
+    UInt32 j;
657
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;
658
+    if (numSubstreams == 0)
659
+      continue;
660
+    if (type == k7zIdSize)
661
+    for (j = 1; j < numSubstreams; j++)
662
+    {
663
+      UInt64 size;
664
+      RINOK(SzReadNumber(sd, &size));
665
+      (*unpackSizes)[si++] = size;
666
+      sum += size;
667
+    }
668
+    (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
669
+  }
670
+  if (type == k7zIdSize)
671
+  {
672
+    RINOK(SzReadID(sd, &type));
673
+  }
674
+
675
+  for (i = 0; i < *numUnpackStreams; i++)
676
+  {
677
+    (*digestsDefined)[i] = 0;
678
+    (*digests)[i] = 0;
679
+  }
680
+
681
+
682
+  for (i = 0; i < numFolders; i++)
683
+  {
684
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;
685
+    if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
686
+      numDigests += numSubstreams;
687
+  }
688
+
689
+ 
690
+  si = 0;
691
+  for (;;)
692
+  {
693
+    if (type == k7zIdCRC)
694
+    {
695
+      int digestIndex = 0;
696
+      Byte *digestsDefined2 = 0;
697
+      UInt32 *digests2 = 0;
698
+      SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
699
+      if (res == SZ_OK)
700
+      {
701
+        for (i = 0; i < numFolders; i++)
702
+        {
703
+          CSzFolder *folder = folders + i;
704
+          UInt32 numSubstreams = folder->NumUnpackStreams;
705
+          if (numSubstreams == 1 && folder->UnpackCRCDefined)
706
+          {
707
+            (*digestsDefined)[si] = 1;
708
+            (*digests)[si] = folder->UnpackCRC;
709
+            si++;
710
+          }
711
+          else
712
+          {
713
+            UInt32 j;
714
+            for (j = 0; j < numSubstreams; j++, digestIndex++)
715
+            {
716
+              (*digestsDefined)[si] = digestsDefined2[digestIndex];
717
+              (*digests)[si] = digests2[digestIndex];
718
+              si++;
719
+            }
720
+          }
721
+        }
722
+      }
723
+      IAlloc_Free(allocTemp, digestsDefined2);
724
+      IAlloc_Free(allocTemp, digests2);
725
+      RINOK(res);
726
+    }
727
+    else if (type == k7zIdEnd)
728
+      return SZ_OK;
729
+    else
730
+    {
731
+      RINOK(SzSkeepData(sd));
732
+    }
733
+    RINOK(SzReadID(sd, &type));
734
+  }
735
+}
736
+
737
+
738
+static SRes SzReadStreamsInfo(
739
+    CSzData *sd,
740
+    UInt64 *dataOffset,
741
+    CSzAr *p,
742
+    UInt32 *numUnpackStreams,
743
+    UInt64 **unpackSizes, /* allocTemp */
744
+    Byte **digestsDefined,   /* allocTemp */
745
+    UInt32 **digests,        /* allocTemp */
746
+    ISzAlloc *alloc,
747
+    ISzAlloc *allocTemp)
748
+{
749
+  for (;;)
750
+  {
751
+    UInt64 type;
752
+    RINOK(SzReadID(sd, &type));
753
+    if ((UInt64)(int)type != type)
754
+      return SZ_ERROR_UNSUPPORTED;
755
+    switch((int)type)
756
+    {
757
+      case k7zIdEnd:
758
+        return SZ_OK;
759
+      case k7zIdPackInfo:
760
+      {
761
+        RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
762
+            &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
763
+        break;
764
+      }
765
+      case k7zIdUnpackInfo:
766
+      {
767
+        RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
768
+        break;
769
+      }
770
+      case k7zIdSubStreamsInfo:
771
+      {
772
+        RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
773
+            numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
774
+        break;
775
+      }
776
+      default:
777
+        return SZ_ERROR_UNSUPPORTED;
778
+    }
779
+  }
780
+}
781
+
782
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
783
+
784
+static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc)
785
+{
786
+  UInt32 i;
787
+  for (i = 0; i < numFiles; i++)
788
+  {
789
+    UInt32 len = 0;
790
+    UInt32 pos = 0;
791
+    CSzFileItem *file = files + i;
792
+    while (pos + 2 <= sd->Size)
793
+    {
794
+      int numAdds;
795
+      UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
796
+      pos += 2;
797
+      len++;
798
+      if (value == 0)
799
+        break;
800
+      if (value < 0x80)
801
+        continue;
802
+      if (value >= 0xD800 && value < 0xE000)
803
+      {
804
+        UInt32 c2;
805
+        if (value >= 0xDC00)
806
+          return SZ_ERROR_ARCHIVE;
807
+        if (pos + 2 > sd->Size)
808
+          return SZ_ERROR_ARCHIVE;
809
+        c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
810
+        pos += 2;
811
+        if (c2 < 0xDC00 || c2 >= 0xE000)
812
+          return SZ_ERROR_ARCHIVE;
813
+        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
814
+      }
815
+      for (numAdds = 1; numAdds < 5; numAdds++)
816
+        if (value < (((UInt32)1) << (numAdds * 5 + 6)))
817
+          break;
818
+      len += numAdds;
819
+    }
820
+
821
+    MY_ALLOC(char, file->Name, (size_t)len, alloc);
822
+
823
+    len = 0;
824
+    while (2 <= sd->Size)
825
+    {
826
+      int numAdds;
827
+      UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
828
+      SzSkeepDataSize(sd, 2);
829
+      if (value < 0x80)
830
+      {
831
+        file->Name[len++] = (char)value;
832
+        if (value == 0)
833
+          break;
834
+        continue;
835
+      }
836
+      if (value >= 0xD800 && value < 0xE000)
837
+      {
838
+        UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
839
+        SzSkeepDataSize(sd, 2);
840
+        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
841
+      }
842
+      for (numAdds = 1; numAdds < 5; numAdds++)
843
+        if (value < (((UInt32)1) << (numAdds * 5 + 6)))
844
+          break;
845
+      file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
846
+      do
847
+      {
848
+        numAdds--;
849
+        file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
850
+      }
851
+      while (numAdds > 0);
852
+
853
+      len += numAdds;
854
+    }
855
+  }
856
+  return SZ_OK;
857
+}
858
+
859
+static SRes SzReadHeader2(
860
+    CSzArEx *p,   /* allocMain */
861
+    CSzData *sd,
862
+    UInt64 **unpackSizes,  /* allocTemp */
863
+    Byte **digestsDefined,    /* allocTemp */
864
+    UInt32 **digests,         /* allocTemp */
865
+    Byte **emptyStreamVector, /* allocTemp */
866
+    Byte **emptyFileVector,   /* allocTemp */
867
+    Byte **lwtVector,         /* allocTemp */
868
+    ISzAlloc *allocMain,
869
+    ISzAlloc *allocTemp)
870
+{
871
+  UInt64 type;
872
+  UInt32 numUnpackStreams = 0;
873
+  UInt32 numFiles = 0;
874
+  CSzFileItem *files = 0;
875
+  UInt32 numEmptyStreams = 0;
876
+  UInt32 i;
877
+
878
+  RINOK(SzReadID(sd, &type));
879
+
880
+  if (type == k7zIdArchiveProperties)
881
+  {
882
+    RINOK(SzReadArchiveProperties(sd));
883
+    RINOK(SzReadID(sd, &type));
884
+  }
885
+ 
886
+ 
887
+  if (type == k7zIdMainStreamsInfo)
888
+  {
889
+    RINOK(SzReadStreamsInfo(sd,
890
+        &p->dataPos,
891
+        &p->db,
892
+        &numUnpackStreams,
893
+        unpackSizes,
894
+        digestsDefined,
895
+        digests, allocMain, allocTemp));
896
+    p->dataPos += p->startPosAfterHeader;
897
+    RINOK(SzReadID(sd, &type));
898
+  }
899
+
900
+  if (type == k7zIdEnd)
901
+    return SZ_OK;
902
+  if (type != k7zIdFilesInfo)
903
+    return SZ_ERROR_ARCHIVE;
904
+  
905
+  RINOK(SzReadNumber32(sd, &numFiles));
906
+  p->db.NumFiles = numFiles;
907
+
908
+  MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
909
+
910
+  p->db.Files = files;
911
+  for (i = 0; i < numFiles; i++)
912
+    SzFile_Init(files + i);
913
+
914
+  for (;;)
915
+  {
916
+    UInt64 type;
917
+    UInt64 size;
918
+    RINOK(SzReadID(sd, &type));
919
+    if (type == k7zIdEnd)
920
+      break;
921
+    RINOK(SzReadNumber(sd, &size));
922
+
923
+    if ((UInt64)(int)type != type)
924
+    {
925
+      RINOK(SzSkeepDataSize(sd, size));
926
+    }
927
+    else
928
+    switch((int)type)
929
+    {
930
+      case k7zIdName:
931
+      {
932
+        RINOK(SzReadSwitch(sd));
933
+        RINOK(SzReadFileNames(sd, numFiles, files, allocMain))
934
+        break;
935
+      }
936
+      case k7zIdEmptyStream:
937
+      {
938
+        RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
939
+        numEmptyStreams = 0;
940
+        for (i = 0; i < numFiles; i++)
941
+          if ((*emptyStreamVector)[i])
942
+            numEmptyStreams++;
943
+        break;
944
+      }
945
+      case k7zIdEmptyFile:
946
+      {
947
+        RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
948
+        break;
949
+      }
950
+      case k7zIdMTime:
951
+      {
952
+        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
953
+        RINOK(SzReadSwitch(sd));
954
+        for (i = 0; i < numFiles; i++)
955
+        {
956
+          CSzFileItem *f = &files[i];
957
+          Byte defined = (*lwtVector)[i];
958
+          f->MTimeDefined = defined;
959
+          f->MTime.Low = f->MTime.High = 0;
960
+          if (defined)
961
+          {
962
+            RINOK(SzReadUInt32(sd, &f->MTime.Low));
963
+            RINOK(SzReadUInt32(sd, &f->MTime.High));
964
+          }
965
+        }
966
+        break;
967
+      }
968
+      default:
969
+      {
970
+        RINOK(SzSkeepDataSize(sd, size));
971
+      }
972
+    }
973
+  }
974
+
975
+  {
976
+    UInt32 emptyFileIndex = 0;
977
+    UInt32 sizeIndex = 0;
978
+    for (i = 0; i < numFiles; i++)
979
+    {
980
+      CSzFileItem *file = files + i;
981
+      file->IsAnti = 0;
982
+      if (*emptyStreamVector == 0)
983
+        file->HasStream = 1;
984
+      else
985
+        file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
986
+      if (file->HasStream)
987
+      {
988
+        file->IsDir = 0;
989
+        file->Size = (*unpackSizes)[sizeIndex];
990
+        file->FileCRC = (*digests)[sizeIndex];
991
+        file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
992
+        sizeIndex++;
993
+      }
994
+      else
995
+      {
996
+        if (*emptyFileVector == 0)
997
+          file->IsDir = 1;
998
+        else
999
+          file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
1000
+        emptyFileIndex++;
1001
+        file->Size = 0;
1002
+        file->FileCRCDefined = 0;
1003
+      }
1004
+    }
1005
+  }
1006
+  return SzArEx_Fill(p, allocMain);
1007
+}
1008
+
1009
+static SRes SzReadHeader(
1010
+    CSzArEx *p,
1011
+    CSzData *sd,
1012
+    ISzAlloc *allocMain,
1013
+    ISzAlloc *allocTemp)
1014
+{
1015
+  UInt64 *unpackSizes = 0;
1016
+  Byte *digestsDefined = 0;
1017
+  UInt32 *digests = 0;
1018
+  Byte *emptyStreamVector = 0;
1019
+  Byte *emptyFileVector = 0;
1020
+  Byte *lwtVector = 0;
1021
+  SRes res = SzReadHeader2(p, sd,
1022
+      &unpackSizes, &digestsDefined, &digests,
1023
+      &emptyStreamVector, &emptyFileVector, &lwtVector,
1024
+      allocMain, allocTemp);
1025
+  IAlloc_Free(allocTemp, unpackSizes);
1026
+  IAlloc_Free(allocTemp, digestsDefined);
1027
+  IAlloc_Free(allocTemp, digests);
1028
+  IAlloc_Free(allocTemp, emptyStreamVector);
1029
+  IAlloc_Free(allocTemp, emptyFileVector);
1030
+  IAlloc_Free(allocTemp, lwtVector);
1031
+  return res;
1032
+}
1033
+
1034
+static SRes SzReadAndDecodePackedStreams2(
1035
+    ILookInStream *inStream,
1036
+    CSzData *sd,
1037
+    CBuf *outBuffer,
1038
+    UInt64 baseOffset,
1039
+    CSzAr *p,
1040
+    UInt64 **unpackSizes,
1041
+    Byte **digestsDefined,
1042
+    UInt32 **digests,
1043
+    ISzAlloc *allocTemp)
1044
+{
1045
+
1046
+  UInt32 numUnpackStreams = 0;
1047
+  UInt64 dataStartPos;
1048
+  CSzFolder *folder;
1049
+  UInt64 unpackSize;
1050
+  SRes res;
1051
+
1052
+  RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
1053
+      &numUnpackStreams,  unpackSizes, digestsDefined, digests,
1054
+      allocTemp, allocTemp));
1055
+  
1056
+  dataStartPos += baseOffset;
1057
+  if (p->NumFolders != 1)
1058
+    return SZ_ERROR_ARCHIVE;
1059
+
1060
+  folder = p->Folders;
1061
+  unpackSize = SzFolder_GetUnpackSize(folder);
1062
+  
1063
+  RINOK(LookInStream_SeekTo(inStream, dataStartPos));
1064
+
1065
+  if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
1066
+    return SZ_ERROR_MEM;
1067
+  
1068
+  res = SzDecode(p->PackSizes, folder,
1069
+          inStream, dataStartPos,
1070
+          outBuffer->data, (size_t)unpackSize, allocTemp);
1071
+  RINOK(res);
1072
+  if (folder->UnpackCRCDefined)
1073
+    if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
1074
+      return SZ_ERROR_CRC;
1075
+  return SZ_OK;
1076
+}
1077
+
1078
+static SRes SzReadAndDecodePackedStreams(
1079
+    ILookInStream *inStream,
1080
+    CSzData *sd,
1081
+    CBuf *outBuffer,
1082
+    UInt64 baseOffset,
1083
+    ISzAlloc *allocTemp)
1084
+{
1085
+  CSzAr p;
1086
+  UInt64 *unpackSizes = 0;
1087
+  Byte *digestsDefined = 0;
1088
+  UInt32 *digests = 0;
1089
+  SRes res;
1090
+  SzAr_Init(&p);
1091
+  res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
1092
+    &p, &unpackSizes, &digestsDefined, &digests,
1093
+    allocTemp);
1094
+  SzAr_Free(&p, allocTemp);
1095
+  IAlloc_Free(allocTemp, unpackSizes);
1096
+  IAlloc_Free(allocTemp, digestsDefined);
1097
+  IAlloc_Free(allocTemp, digests);
1098
+  return res;
1099
+}
1100
+
1101
+static SRes SzArEx_Open2(
1102
+    CSzArEx *p,
1103
+    ILookInStream *inStream,
1104
+    ISzAlloc *allocMain,
1105
+    ISzAlloc *allocTemp)
1106
+{
1107
+  Byte header[k7zStartHeaderSize];
1108
+  UInt64 nextHeaderOffset, nextHeaderSize;
1109
+  size_t nextHeaderSizeT;
1110
+  UInt32 nextHeaderCRC;
1111
+  CBuf buffer;
1112
+  SRes res;
1113
+
1114
+  RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
1115
+
1116
+  if (!TestSignatureCandidate(header))
1117
+    return SZ_ERROR_NO_ARCHIVE;
1118
+  if (header[6] != k7zMajorVersion)
1119
+    return SZ_ERROR_UNSUPPORTED;
1120
+
1121
+  nextHeaderOffset = GetUi64(header + 12);
1122
+  nextHeaderSize = GetUi64(header + 20);
1123
+  nextHeaderCRC = GetUi32(header + 28);
1124
+
1125
+  p->startPosAfterHeader = k7zStartHeaderSize;
1126
+  
1127
+  if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
1128
+    return SZ_ERROR_CRC;
1129
+
1130
+  nextHeaderSizeT = (size_t)nextHeaderSize;
1131
+  if (nextHeaderSizeT != nextHeaderSize)
1132
+    return SZ_ERROR_MEM;
1133
+  if (nextHeaderSizeT == 0)
1134
+    return SZ_OK;
1135
+  if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
1136
+      nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
1137
+    return SZ_ERROR_NO_ARCHIVE;
1138
+
1139
+  {
1140
+    Int64 pos = 0;
1141
+    RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
1142
+    if ((UInt64)pos < nextHeaderOffset ||
1143
+        (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
1144
+        (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
1145
+      return SZ_ERROR_INPUT_EOF;
1146
+  }
1147
+
1148
+  RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
1149
+
1150
+  if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
1151
+    return SZ_ERROR_MEM;
1152
+
1153
+  res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
1154
+  if (res == SZ_OK)
1155
+  {
1156
+    res = SZ_ERROR_ARCHIVE;
1157
+    if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
1158
+    {
1159
+      CSzData sd;
1160
+      UInt64 type;
1161
+      sd.Data = buffer.data;
1162
+      sd.Size = buffer.size;
1163
+      res = SzReadID(&sd, &type);
1164
+      if (res == SZ_OK)
1165
+      {
1166
+        if (type == k7zIdEncodedHeader)
1167
+        {
1168
+          CBuf outBuffer;
1169
+          Buf_Init(&outBuffer);
1170
+          res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
1171
+          if (res != SZ_OK)
1172
+            Buf_Free(&outBuffer, allocTemp);
1173
+          else
1174
+          {
1175
+            Buf_Free(&buffer, allocTemp);
1176
+            buffer.data = outBuffer.data;
1177
+            buffer.size = outBuffer.size;
1178
+            sd.Data = buffer.data;
1179
+            sd.Size = buffer.size;
1180
+            res = SzReadID(&sd, &type);
1181
+          }
1182
+        }
1183
+      }
1184
+      if (res == SZ_OK)
1185
+      {
1186
+        if (type == k7zIdHeader)
1187
+          res = SzReadHeader(p, &sd, allocMain, allocTemp);
1188
+        else
1189
+          res = SZ_ERROR_UNSUPPORTED;
1190
+      }
1191
+    }
1192
+  }
1193
+  Buf_Free(&buffer, allocTemp);
1194
+  return res;
1195
+}
1196
+
1197
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
1198
+{
1199
+  SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
1200
+  if (res != SZ_OK)
1201
+    SzArEx_Free(p, allocMain);
1202
+  return res;
1203
+}
0 1204
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+/* 7zIn.h -- 7z Input functions
1
+2008-11-23 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __7Z_IN_H
4
+#define __7Z_IN_H
5
+
6
+#include "7zHeader.h"
7
+#include "7zItem.h"
8
+
9
+typedef struct
10
+{
11
+  CSzAr db;
12
+  
13
+  UInt64 startPosAfterHeader;
14
+  UInt64 dataPos;
15
+
16
+  UInt32 *FolderStartPackStreamIndex;
17
+  UInt64 *PackStreamStartPositions;
18
+  UInt32 *FolderStartFileIndex;
19
+  UInt32 *FileIndexToFolderIndexMap;
20
+} CSzArEx;
21
+
22
+void SzArEx_Init(CSzArEx *p);
23
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
24
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
25
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
26
+
27
+/*
28
+Errors:
29
+SZ_ERROR_NO_ARCHIVE
30
+SZ_ERROR_ARCHIVE
31
+SZ_ERROR_UNSUPPORTED
32
+SZ_ERROR_MEM
33
+SZ_ERROR_CRC
34
+SZ_ERROR_INPUT_EOF
35
+SZ_ERROR_FAIL
36
+*/
37
+
38
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
39
+ 
40
+#endif
0 41
new file mode 100644
... ...
@@ -0,0 +1,127 @@
0
+/* 7zItem.c -- 7z Items
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#include "7zItem.h"
4
+
5
+void SzCoderInfo_Init(CSzCoderInfo *p)
6
+{
7
+  Buf_Init(&p->Props);
8
+}
9
+
10
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
11
+{
12
+  Buf_Free(&p->Props, alloc);
13
+  SzCoderInfo_Init(p);
14
+}
15
+
16
+void SzFolder_Init(CSzFolder *p)
17
+{
18
+  p->Coders = 0;
19
+  p->BindPairs = 0;
20
+  p->PackStreams = 0;
21
+  p->UnpackSizes = 0;
22
+  p->NumCoders = 0;
23
+  p->NumBindPairs = 0;
24
+  p->NumPackStreams = 0;
25
+  p->UnpackCRCDefined = 0;
26
+  p->UnpackCRC = 0;
27
+  p->NumUnpackStreams = 0;
28
+}
29
+
30
+void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
31
+{
32
+  UInt32 i;
33
+  if (p->Coders)
34
+    for (i = 0; i < p->NumCoders; i++)
35
+      SzCoderInfo_Free(&p->Coders[i], alloc);
36
+  IAlloc_Free(alloc, p->Coders);
37
+  IAlloc_Free(alloc, p->BindPairs);
38
+  IAlloc_Free(alloc, p->PackStreams);
39
+  IAlloc_Free(alloc, p->UnpackSizes);
40
+  SzFolder_Init(p);
41
+}
42
+
43
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
44
+{
45
+  UInt32 result = 0;
46
+  UInt32 i;
47
+  for (i = 0; i < p->NumCoders; i++)
48
+    result += p->Coders[i].NumOutStreams;
49
+  return result;
50
+}
51
+
52
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
53
+{
54
+  UInt32 i;
55
+  for (i = 0; i < p->NumBindPairs; i++)
56
+    if (p->BindPairs[i].InIndex == inStreamIndex)
57
+      return i;
58
+  return -1;
59
+}
60
+
61
+
62
+int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
63
+{
64
+  UInt32 i;
65
+  for (i = 0; i < p->NumBindPairs; i++)
66
+    if (p->BindPairs[i].OutIndex == outStreamIndex)
67
+      return i;
68
+  return -1;
69
+}
70
+
71
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
72
+{
73
+  int i = (int)SzFolder_GetNumOutStreams(p);
74
+  if (i == 0)
75
+    return 0;
76
+  for (i--; i >= 0; i--)
77
+    if (SzFolder_FindBindPairForOutStream(p, i) < 0)
78
+      return p->UnpackSizes[i];
79
+  /* throw 1; */
80
+  return 0;
81
+}
82
+
83
+void SzFile_Init(CSzFileItem *p)
84
+{
85
+  p->HasStream = 1;
86
+  p->IsDir = 0;
87
+  p->IsAnti = 0;
88
+  p->FileCRCDefined = 0;
89
+  p->MTimeDefined = 0;
90
+  p->Name = 0;
91
+}
92
+
93
+static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc)
94
+{
95
+  IAlloc_Free(alloc, p->Name);
96
+  SzFile_Init(p);
97
+}
98
+
99
+void SzAr_Init(CSzAr *p)
100
+{
101
+  p->PackSizes = 0;
102
+  p->PackCRCsDefined = 0;
103
+  p->PackCRCs = 0;
104
+  p->Folders = 0;
105
+  p->Files = 0;
106
+  p->NumPackStreams = 0;
107
+  p->NumFolders = 0;
108
+  p->NumFiles = 0;
109
+}
110
+
111
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
112
+{
113
+  UInt32 i;
114
+  if (p->Folders)
115
+    for (i = 0; i < p->NumFolders; i++)
116
+      SzFolder_Free(&p->Folders[i], alloc);
117
+  if (p->Files)
118
+    for (i = 0; i < p->NumFiles; i++)
119
+      SzFile_Free(&p->Files[i], alloc);
120
+  IAlloc_Free(alloc, p->PackSizes);
121
+  IAlloc_Free(alloc, p->PackCRCsDefined);
122
+  IAlloc_Free(alloc, p->PackCRCs);
123
+  IAlloc_Free(alloc, p->Folders);
124
+  IAlloc_Free(alloc, p->Files);
125
+  SzAr_Init(p);
126
+}
0 127
new file mode 100644
... ...
@@ -0,0 +1,84 @@
0
+/* 7zItem.h -- 7z Items
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __7Z_ITEM_H
4
+#define __7Z_ITEM_H
5
+
6
+#include "../../7zBuf.h"
7
+
8
+typedef struct
9
+{
10
+  UInt32 NumInStreams;
11
+  UInt32 NumOutStreams;
12
+  UInt64 MethodID;
13
+  CBuf Props;
14
+} CSzCoderInfo;
15
+
16
+void SzCoderInfo_Init(CSzCoderInfo *p);
17
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
18
+
19
+typedef struct
20
+{
21
+  UInt32 InIndex;
22
+  UInt32 OutIndex;
23
+} CBindPair;
24
+
25
+typedef struct
26
+{
27
+  CSzCoderInfo *Coders;
28
+  CBindPair *BindPairs;
29
+  UInt32 *PackStreams;
30
+  UInt64 *UnpackSizes;
31
+  UInt32 NumCoders;
32
+  UInt32 NumBindPairs;
33
+  UInt32 NumPackStreams;
34
+  int UnpackCRCDefined;
35
+  UInt32 UnpackCRC;
36
+
37
+  UInt32 NumUnpackStreams;
38
+} CSzFolder;
39
+
40
+void SzFolder_Init(CSzFolder *p);
41
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
42
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
43
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
44
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
45
+
46
+typedef struct
47
+{
48
+  UInt32 Low;
49
+  UInt32 High;
50
+} CNtfsFileTime;
51
+
52
+typedef struct
53
+{
54
+  CNtfsFileTime MTime;
55
+  UInt64 Size;
56
+  char *Name;
57
+  UInt32 FileCRC;
58
+
59
+  Byte HasStream;
60
+  Byte IsDir;
61
+  Byte IsAnti;
62
+  Byte FileCRCDefined;
63
+  Byte MTimeDefined;
64
+} CSzFileItem;
65
+
66
+void SzFile_Init(CSzFileItem *p);
67
+
68
+typedef struct
69
+{
70
+  UInt64 *PackSizes;
71
+  Byte *PackCRCsDefined;
72
+  UInt32 *PackCRCs;
73
+  CSzFolder *Folders;
74
+  CSzFileItem *Files;
75
+  UInt32 NumPackStreams;
76
+  UInt32 NumFolders;
77
+  UInt32 NumFiles;
78
+} CSzAr;
79
+
80
+void SzAr_Init(CSzAr *p);
81
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
82
+
83
+#endif
0 84
new file mode 100644
... ...
@@ -0,0 +1,132 @@
0
+/* Bcj2.c -- Converter for x86 code (BCJ2)
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#include "Bcj2.h"
4
+
5
+#ifdef _LZMA_PROB32
6
+#define CProb UInt32
7
+#else
8
+#define CProb UInt16
9
+#endif
10
+
11
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
12
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
13
+
14
+#define kNumTopBits 24
15
+#define kTopValue ((UInt32)1 << kNumTopBits)
16
+
17
+#define kNumBitModelTotalBits 11
18
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
19
+#define kNumMoveBits 5
20
+
21
+#define RC_READ_BYTE (*buffer++)
22
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
23
+#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
24
+  { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
25
+
26
+#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
27
+
28
+#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
29
+#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
30
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
31
+
32
+int Bcj2_Decode(
33
+    const Byte *buf0, SizeT size0,
34
+    const Byte *buf1, SizeT size1,
35
+    const Byte *buf2, SizeT size2,
36
+    const Byte *buf3, SizeT size3,
37
+    Byte *outBuf, SizeT outSize)
38
+{
39
+  CProb p[256 + 2];
40
+  SizeT inPos = 0, outPos = 0;
41
+
42
+  const Byte *buffer, *bufferLim;
43
+  UInt32 range, code;
44
+  Byte prevByte = 0;
45
+
46
+  unsigned int i;
47
+  for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
48
+    p[i] = kBitModelTotal >> 1;
49
+
50
+  buffer = buf3;
51
+  bufferLim = buffer + size3;
52
+  RC_INIT2
53
+
54
+  if (outSize == 0)
55
+    return SZ_OK;
56
+
57
+  for (;;)
58
+  {
59
+    Byte b;
60
+    CProb *prob;
61
+    UInt32 bound;
62
+    UInt32 ttt;
63
+
64
+    SizeT limit = size0 - inPos;
65
+    if (outSize - outPos < limit)
66
+      limit = outSize - outPos;
67
+    while (limit != 0)
68
+    {
69
+      Byte b = buf0[inPos];
70
+      outBuf[outPos++] = b;
71
+      if (IsJ(prevByte, b))
72
+        break;
73
+      inPos++;
74
+      prevByte = b;
75
+      limit--;
76
+    }
77
+
78
+    if (limit == 0 || outPos == outSize)
79
+      break;
80
+
81
+    b = buf0[inPos++];
82
+
83
+    if (b == 0xE8)
84
+      prob = p + prevByte;
85
+    else if (b == 0xE9)
86
+      prob = p + 256;
87
+    else
88
+      prob = p + 257;
89
+
90
+    IF_BIT_0(prob)
91
+    {
92
+      UPDATE_0(prob)
93
+      prevByte = b;
94
+    }
95
+    else
96
+    {
97
+      UInt32 dest;
98
+      const Byte *v;
99
+      UPDATE_1(prob)
100
+      if (b == 0xE8)
101
+      {
102
+        v = buf1;
103
+        if (size1 < 4)
104
+          return SZ_ERROR_DATA;
105
+        buf1 += 4;
106
+        size1 -= 4;
107
+      }
108
+      else
109
+      {
110
+        v = buf2;
111
+        if (size2 < 4)
112
+          return SZ_ERROR_DATA;
113
+        buf2 += 4;
114
+        size2 -= 4;
115
+      }
116
+      dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
117
+          ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
118
+      outBuf[outPos++] = (Byte)dest;
119
+      if (outPos == outSize)
120
+        break;
121
+      outBuf[outPos++] = (Byte)(dest >> 8);
122
+      if (outPos == outSize)
123
+        break;
124
+      outBuf[outPos++] = (Byte)(dest >> 16);
125
+      if (outPos == outSize)
126
+        break;
127
+      outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
128
+    }
129
+  }
130
+  return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
131
+}
0 132
new file mode 100644
... ...
@@ -0,0 +1,30 @@
0
+/* Bcj2.h -- Converter for x86 code (BCJ2)
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __BCJ2_H
4
+#define __BCJ2_H
5
+
6
+#include "Types.h"
7
+
8
+/*
9
+Conditions:
10
+  outSize <= FullOutputSize,
11
+  where FullOutputSize is full size of output stream of x86_2 filter.
12
+
13
+If buf0 overlaps outBuf, there are two required conditions:
14
+  1) (buf0 >= outBuf)
15
+  2) (buf0 + size0 >= outBuf + FullOutputSize).
16
+
17
+Returns:
18
+  SZ_OK
19
+  SZ_ERROR_DATA - Data error
20
+*/
21
+
22
+int Bcj2_Decode(
23
+    const Byte *buf0, SizeT size0,
24
+    const Byte *buf1, SizeT size1,
25
+    const Byte *buf2, SizeT size2,
26
+    const Byte *buf3, SizeT size3,
27
+    Byte *outBuf, SizeT outSize);
28
+
29
+#endif
0 30
new file mode 100644
... ...
@@ -0,0 +1,133 @@
0
+/* Bra.c -- Converters for RISC code
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#include "Bra.h"
4
+
5
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
6
+{
7
+  SizeT i;
8
+  if (size < 4)
9
+    return 0;
10
+  size -= 4;
11
+  ip += 8;
12
+  for (i = 0; i <= size; i += 4)
13
+  {
14
+    if (data[i + 3] == 0xEB)
15
+    {
16
+      UInt32 dest;
17
+      UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
18
+      src <<= 2;
19
+      if (encoding)
20
+        dest = ip + (UInt32)i + src;
21
+      else
22
+        dest = src - (ip + (UInt32)i);
23
+      dest >>= 2;
24
+      data[i + 2] = (Byte)(dest >> 16);
25
+      data[i + 1] = (Byte)(dest >> 8);
26
+      data[i + 0] = (Byte)dest;
27
+    }
28
+  }
29
+  return i;
30
+}
31
+
32
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
33
+{
34
+  SizeT i;
35
+  if (size < 4)
36
+    return 0;
37
+  size -= 4;
38
+  ip += 4;
39
+  for (i = 0; i <= size; i += 2)
40
+  {
41
+    if ((data[i + 1] & 0xF8) == 0xF0 &&
42
+        (data[i + 3] & 0xF8) == 0xF8)
43
+    {
44
+      UInt32 dest;
45
+      UInt32 src =
46
+        (((UInt32)data[i + 1] & 0x7) << 19) |
47
+        ((UInt32)data[i + 0] << 11) |
48
+        (((UInt32)data[i + 3] & 0x7) << 8) |
49
+        (data[i + 2]);
50
+      
51
+      src <<= 1;
52
+      if (encoding)
53
+        dest = ip + (UInt32)i + src;
54
+      else
55
+        dest = src - (ip + (UInt32)i);
56
+      dest >>= 1;
57
+      
58
+      data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
59
+      data[i + 0] = (Byte)(dest >> 11);
60
+      data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
61
+      data[i + 2] = (Byte)dest;
62
+      i += 2;
63
+    }
64
+  }
65
+  return i;
66
+}
67
+
68
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
69
+{
70
+  SizeT i;
71
+  if (size < 4)
72
+    return 0;
73
+  size -= 4;
74
+  for (i = 0; i <= size; i += 4)
75
+  {
76
+    if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
77
+    {
78
+      UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
79
+        ((UInt32)data[i + 1] << 16) |
80
+        ((UInt32)data[i + 2] << 8) |
81
+        ((UInt32)data[i + 3] & (~3));
82
+      
83
+      UInt32 dest;
84
+      if (encoding)
85
+        dest = ip + (UInt32)i + src;
86
+      else
87
+        dest = src - (ip + (UInt32)i);
88
+      data[i + 0] = (Byte)(0x48 | ((dest >> 24) &  0x3));
89
+      data[i + 1] = (Byte)(dest >> 16);
90
+      data[i + 2] = (Byte)(dest >> 8);
91
+      data[i + 3] &= 0x3;
92
+      data[i + 3] |= dest;
93
+    }
94
+  }
95
+  return i;
96
+}
97
+
98
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
99
+{
100
+  UInt32 i;
101
+  if (size < 4)
102
+    return 0;
103
+  size -= 4;
104
+  for (i = 0; i <= size; i += 4)
105
+  {
106
+    if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
107
+        data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
108
+    {
109
+      UInt32 src =
110
+        ((UInt32)data[i + 0] << 24) |
111
+        ((UInt32)data[i + 1] << 16) |
112
+        ((UInt32)data[i + 2] << 8) |
113
+        ((UInt32)data[i + 3]);
114
+      UInt32 dest;
115
+      
116
+      src <<= 2;
117
+      if (encoding)
118
+        dest = ip + i + src;
119
+      else
120
+        dest = src - (ip + i);
121
+      dest >>= 2;
122
+      
123
+      dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
124
+
125
+      data[i + 0] = (Byte)(dest >> 24);
126
+      data[i + 1] = (Byte)(dest >> 16);
127
+      data[i + 2] = (Byte)(dest >> 8);
128
+      data[i + 3] = (Byte)dest;
129
+    }
130
+  }
131
+  return i;
132
+}
0 133
new file mode 100644
... ...
@@ -0,0 +1,60 @@
0
+/* Bra.h -- Branch converters for executables
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#ifndef __BRA_H
4
+#define __BRA_H
5
+
6
+#include "Types.h"
7
+
8
+/*
9
+These functions convert relative addresses to absolute addresses
10
+in CALL instructions to increase the compression ratio.
11
+  
12
+  In:
13
+    data     - data buffer
14
+    size     - size of data
15
+    ip       - current virtual Instruction Pinter (IP) value
16
+    state    - state variable for x86 converter
17
+    encoding - 0 (for decoding), 1 (for encoding)
18
+  
19
+  Out:
20
+    state    - state variable for x86 converter
21
+
22
+  Returns:
23
+    The number of processed bytes. If you call these functions with multiple calls,
24
+    you must start next call with first byte after block of processed bytes.
25
+  
26
+  Type   Endian  Alignment  LookAhead
27
+  
28
+  x86    little      1          4
29
+  ARMT   little      2          2
30
+  ARM    little      4          0
31
+  PPC     big        4          0
32
+  SPARC   big        4          0
33
+  IA64   little     16          0
34
+
35
+  size must be >= Alignment + LookAhead, if it's not last block.
36
+  If (size < Alignment + LookAhead), converter returns 0.
37
+
38
+  Example:
39
+
40
+    UInt32 ip = 0;
41
+    for ()
42
+    {
43
+      ; size must be >= Alignment + LookAhead, if it's not last block
44
+      SizeT processed = Convert(data, size, ip, 1);
45
+      data += processed;
46
+      size -= processed;
47
+      ip += processed;
48
+    }
49
+*/
50
+
51
+#define x86_Convert_Init(state) { state = 0; }
52
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
53
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
54
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
55
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
56
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
57
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
58
+
59
+#endif
0 60
new file mode 100644
... ...
@@ -0,0 +1,85 @@
0
+/* Bra86.c -- Converter for x86 code (BCJ)
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#include "Bra.h"
4
+
5
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
6
+
7
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
8
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
9
+
10
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
11
+{
12
+  SizeT bufferPos = 0, prevPosT;
13
+  UInt32 prevMask = *state & 0x7;
14
+  if (size < 5)
15
+    return 0;
16
+  ip += 5;
17
+  prevPosT = (SizeT)0 - 1;
18
+
19
+  for (;;)
20
+  {
21
+    Byte *p = data + bufferPos;
22
+    Byte *limit = data + size - 4;
23
+    for (; p < limit; p++)
24
+      if ((*p & 0xFE) == 0xE8)
25
+        break;
26
+    bufferPos = (SizeT)(p - data);
27
+    if (p >= limit)
28
+      break;
29
+    prevPosT = bufferPos - prevPosT;
30
+    if (prevPosT > 3)
31
+      prevMask = 0;
32
+    else
33
+    {
34
+      prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
35
+      if (prevMask != 0)
36
+      {
37
+        Byte b = p[4 - kMaskToBitNumber[prevMask]];
38
+        if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
39
+        {
40
+          prevPosT = bufferPos;
41
+          prevMask = ((prevMask << 1) & 0x7) | 1;
42
+          bufferPos++;
43
+          continue;
44
+        }
45
+      }
46
+    }
47
+    prevPosT = bufferPos;
48
+
49
+    if (Test86MSByte(p[4]))
50
+    {
51
+      UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
52
+      UInt32 dest;
53
+      for (;;)
54
+      {
55
+        Byte b;
56
+        int index;
57
+        if (encoding)
58
+          dest = (ip + (UInt32)bufferPos) + src;
59
+        else
60
+          dest = src - (ip + (UInt32)bufferPos);
61
+        if (prevMask == 0)
62
+          break;
63
+        index = kMaskToBitNumber[prevMask] * 8;
64
+        b = (Byte)(dest >> (24 - index));
65
+        if (!Test86MSByte(b))
66
+          break;
67
+        src = dest ^ ((1 << (32 - index)) - 1);
68
+      }
69
+      p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
70
+      p[3] = (Byte)(dest >> 16);
71
+      p[2] = (Byte)(dest >> 8);
72
+      p[1] = (Byte)dest;
73
+      bufferPos += 5;
74
+    }
75
+    else
76
+    {
77
+      prevMask = ((prevMask << 1) & 0x7) | 1;
78
+      bufferPos++;
79
+    }
80
+  }
81
+  prevPosT = bufferPos - prevPosT;
82
+  *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
83
+  return bufferPos;
84
+}
0 85
new file mode 100644
... ...
@@ -0,0 +1,67 @@
0
+/* BraIA64.c -- Converter for IA-64 code
1
+2008-10-04 : Igor Pavlov : Public domain */
2
+
3
+#include "Bra.h"
4
+
5
+static const Byte kBranchTable[32] =
6
+{
7
+  0, 0, 0, 0, 0, 0, 0, 0,
8
+  0, 0, 0, 0, 0, 0, 0, 0,
9
+  4, 4, 6, 6, 0, 0, 7, 7,
10
+  4, 4, 0, 0, 4, 4, 0, 0
11
+};
12
+
13
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
14
+{
15
+  SizeT i;
16
+  if (size < 16)
17
+    return 0;
18
+  size -= 16;
19
+  for (i = 0; i <= size; i += 16)
20
+  {
21
+    UInt32 instrTemplate = data[i] & 0x1F;
22
+    UInt32 mask = kBranchTable[instrTemplate];
23
+    UInt32 bitPos = 5;
24
+    int slot;
25
+    for (slot = 0; slot < 3; slot++, bitPos += 41)
26
+    {
27
+      UInt32 bytePos, bitRes;
28
+      UInt64 instruction, instNorm;
29
+      int j;
30
+      if (((mask >> slot) & 1) == 0)
31
+        continue;
32
+      bytePos = (bitPos >> 3);
33
+      bitRes = bitPos & 0x7;
34
+      instruction = 0;
35
+      for (j = 0; j < 6; j++)
36
+        instruction += (UInt64)data[i + j + bytePos] << (8 * j);
37
+
38
+      instNorm = instruction >> bitRes;
39
+      if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
40
+      {
41
+        UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
42
+        UInt32 dest;
43
+        src |= ((UInt32)(instNorm >> 36) & 1) << 20;
44
+        
45
+        src <<= 4;
46
+        
47
+        if (encoding)
48
+          dest = ip + (UInt32)i + src;
49
+        else
50
+          dest = src - (ip + (UInt32)i);
51
+        
52
+        dest >>= 4;
53
+        
54
+        instNorm &= ~((UInt64)(0x8FFFFF) << 13);
55
+        instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
56
+        instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
57
+        
58
+        instruction &= (1 << bitRes) - 1;
59
+        instruction |= (instNorm << bitRes);
60
+        for (j = 0; j < 6; j++)
61
+          data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
62
+      }
63
+    }
64
+  }
65
+  return i;
66
+}
0 67
new file mode 100644
... ...
@@ -0,0 +1,69 @@
0
+/* CpuArch.h
1
+2008-08-05
2
+Igor Pavlov
3
+Public domain */
4
+
5
+#ifndef __CPUARCH_H
6
+#define __CPUARCH_H
7
+
8
+/*
9
+LITTLE_ENDIAN_UNALIGN means:
10
+  1) CPU is LITTLE_ENDIAN
11
+  2) it's allowed to make unaligned memory accesses
12
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
13
+about these properties of platform.
14
+*/
15
+
16
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
17
+#define LITTLE_ENDIAN_UNALIGN
18
+#endif
19
+
20
+#ifdef LITTLE_ENDIAN_UNALIGN
21
+
22
+#define GetUi16(p) (*(const UInt16 *)(p))
23
+#define GetUi32(p) (*(const UInt32 *)(p))
24
+#define GetUi64(p) (*(const UInt64 *)(p))
25
+#define SetUi32(p, d) *(UInt32 *)(p) = (d);
26
+
27
+#else
28
+
29
+#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
30
+
31
+#define GetUi32(p) ( \
32
+             ((const Byte *)(p))[0]        | \
33
+    ((UInt32)((const Byte *)(p))[1] <<  8) | \
34
+    ((UInt32)((const Byte *)(p))[2] << 16) | \
35
+    ((UInt32)((const Byte *)(p))[3] << 24))
36
+
37
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
38
+
39
+#define SetUi32(p, d) { UInt32 _x_ = (d); \
40
+    ((Byte *)(p))[0] = (Byte)_x_; \
41
+    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
42
+    ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
43
+    ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
44
+
45
+#endif
46
+
47
+#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
48
+
49
+#pragma intrinsic(_byteswap_ulong)
50
+#pragma intrinsic(_byteswap_uint64)
51
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
52
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
53
+
54
+#else
55
+
56
+#define GetBe32(p) ( \
57
+    ((UInt32)((const Byte *)(p))[0] << 24) | \
58
+    ((UInt32)((const Byte *)(p))[1] << 16) | \
59
+    ((UInt32)((const Byte *)(p))[2] <<  8) | \
60
+             ((const Byte *)(p))[3] )
61
+
62
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
63
+
64
+#endif
65
+
66
+#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
67
+
68
+#endif
0 69
old mode 100755
1 70
new mode 100644
2 71
old mode 100755
3 72
new mode 100644
4 73
old mode 100755
5 74
new mode 100644
... ...
@@ -267,6 +267,32 @@ libclamav_la_SOURCES = \
267 267
 	7z/Types.h \
268 268
 	lzma_iface.c \
269 269
 	lzma_iface.h \
270
+	7z.c \
271
+	7z.h \
272
+	7z/7zFile.c \
273
+	7z/7zFile.h \
274
+	7z/7zStream.c \
275
+	7z/CpuArch.h \
276
+	7z/7zCrc.c \
277
+	7z/7zCrc.h \
278
+	7z/7zBuf.c \
279
+	7z/7zBuf.h \
280
+	7z/Bcj2.c \
281
+	7z/Bcj2.h \
282
+	7z/Bra.c \
283
+	7z/Bra.h \
284
+	7z/Bra86.c \
285
+	7z/BraIA64.c \
286
+	7z/Archive/7z/7zIn.c \
287
+	7z/Archive/7z/7zIn.h \
288
+	7z/Archive/7z/7zDecode.c \
289
+	7z/Archive/7z/7zDecode.h \
290
+	7z/Archive/7z/7zItem.c \
291
+	7z/Archive/7z/7zItem.h \
292
+	7z/Archive/7z/7zHeader.c \
293
+	7z/Archive/7z/7zHeader.h \
294
+	7z/Archive/7z/7zExtract.c \
295
+	7z/Archive/7z/7zExtract.h \
270 296
 	explode.c \
271 297
 	explode.h \
272 298
 	textnorm.c \
... ...
@@ -118,13 +118,20 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \
118 118
 	mspack.c mspack.h cab.c cab.h entconv.c entconv.h entitylist.h \
119 119
 	encoding_aliases.h hashtab.c hashtab.h dconf.c dconf.h \
120 120
 	7z/LzmaDec.c 7z/LzmaDec.h 7z/Types.h lzma_iface.c lzma_iface.h \
121
-	explode.c explode.h textnorm.c textnorm.h dlp.c dlp.h \
122
-	jsparse/js-norm.c jsparse/js-norm.h jsparse/lexglobal.h \
123
-	jsparse/textbuf.h uniq.c uniq.h version.c version.h mpool.c \
124
-	mpool.h default.h sha256.c sha256.h bignum.h bytecode.c \
125
-	bytecode.h bytecode_vm.c bytecode_priv.h clambc.h cpio.c \
126
-	cpio.h macho.c macho.h ishield.c ishield.h bignum.c \
127
-	bignum_class.h
121
+	7z.c 7z.h 7z/7zFile.c 7z/7zFile.h 7z/7zStream.c 7z/CpuArch.h \
122
+	7z/7zCrc.c 7z/7zCrc.h 7z/7zBuf.c 7z/7zBuf.h 7z/Bcj2.c \
123
+	7z/Bcj2.h 7z/Bra.c 7z/Bra.h 7z/Bra86.c 7z/BraIA64.c \
124
+	7z/Archive/7z/7zIn.c 7z/Archive/7z/7zIn.h \
125
+	7z/Archive/7z/7zDecode.c 7z/Archive/7z/7zDecode.h \
126
+	7z/Archive/7z/7zItem.c 7z/Archive/7z/7zItem.h \
127
+	7z/Archive/7z/7zHeader.c 7z/Archive/7z/7zHeader.h \
128
+	7z/Archive/7z/7zExtract.c 7z/Archive/7z/7zExtract.h explode.c \
129
+	explode.h textnorm.c textnorm.h dlp.c dlp.h jsparse/js-norm.c \
130
+	jsparse/js-norm.h jsparse/lexglobal.h jsparse/textbuf.h uniq.c \
131
+	uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \
132
+	sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \
133
+	bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \
134
+	ishield.c ishield.h bignum.c bignum_class.h
128 135
 @LINK_TOMMATH_FALSE@am__objects_1 = libclamav_la-bignum.lo
129 136
 am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
130 137
 	libclamav_la-matcher-bm.lo libclamav_la-matcher.lo \
... ...
@@ -158,13 +165,19 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
158 158
 	libclamav_la-cab.lo libclamav_la-entconv.lo \
159 159
 	libclamav_la-hashtab.lo libclamav_la-dconf.lo \
160 160
 	libclamav_la-LzmaDec.lo libclamav_la-lzma_iface.lo \
161
-	libclamav_la-explode.lo libclamav_la-textnorm.lo \
162
-	libclamav_la-dlp.lo libclamav_la-js-norm.lo \
163
-	libclamav_la-uniq.lo libclamav_la-version.lo \
164
-	libclamav_la-mpool.lo libclamav_la-sha256.lo \
165
-	libclamav_la-bytecode.lo libclamav_la-bytecode_vm.lo \
166
-	libclamav_la-cpio.lo libclamav_la-macho.lo \
167
-	libclamav_la-ishield.lo $(am__objects_1)
161
+	libclamav_la-7z.lo libclamav_la-7zFile.lo \
162
+	libclamav_la-7zStream.lo libclamav_la-7zCrc.lo \
163
+	libclamav_la-7zBuf.lo libclamav_la-Bcj2.lo libclamav_la-Bra.lo \
164
+	libclamav_la-Bra86.lo libclamav_la-BraIA64.lo \
165
+	libclamav_la-7zIn.lo libclamav_la-7zDecode.lo \
166
+	libclamav_la-7zItem.lo libclamav_la-7zHeader.lo \
167
+	libclamav_la-7zExtract.lo libclamav_la-explode.lo \
168
+	libclamav_la-textnorm.lo libclamav_la-dlp.lo \
169
+	libclamav_la-js-norm.lo libclamav_la-uniq.lo \
170
+	libclamav_la-version.lo libclamav_la-mpool.lo \
171
+	libclamav_la-sha256.lo libclamav_la-bytecode.lo \
172
+	libclamav_la-bytecode_vm.lo libclamav_la-cpio.lo \
173
+	libclamav_la-macho.lo libclamav_la-ishield.lo $(am__objects_1)
168 174
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
169 175
 libclamav_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
170 176
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libclamav_la_CFLAGS) \
... ...
@@ -521,13 +534,20 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \
521 521
 	regex_suffix.c regex_suffix.h mspack.c mspack.h cab.c cab.h \
522 522
 	entconv.c entconv.h entitylist.h encoding_aliases.h hashtab.c \
523 523
 	hashtab.h dconf.c dconf.h 7z/LzmaDec.c 7z/LzmaDec.h 7z/Types.h \
524
-	lzma_iface.c lzma_iface.h explode.c explode.h textnorm.c \
525
-	textnorm.h dlp.c dlp.h jsparse/js-norm.c jsparse/js-norm.h \
526
-	jsparse/lexglobal.h jsparse/textbuf.h uniq.c uniq.h version.c \
527
-	version.h mpool.c mpool.h default.h sha256.c sha256.h bignum.h \
528
-	bytecode.c bytecode.h bytecode_vm.c bytecode_priv.h clambc.h \
529
-	cpio.c cpio.h macho.c macho.h ishield.c ishield.h \
530
-	$(am__append_7)
524
+	lzma_iface.c lzma_iface.h 7z.c 7z.h 7z/7zFile.c 7z/7zFile.h \
525
+	7z/7zStream.c 7z/CpuArch.h 7z/7zCrc.c 7z/7zCrc.h 7z/7zBuf.c \
526
+	7z/7zBuf.h 7z/Bcj2.c 7z/Bcj2.h 7z/Bra.c 7z/Bra.h 7z/Bra86.c \
527
+	7z/BraIA64.c 7z/Archive/7z/7zIn.c 7z/Archive/7z/7zIn.h \
528
+	7z/Archive/7z/7zDecode.c 7z/Archive/7z/7zDecode.h \
529
+	7z/Archive/7z/7zItem.c 7z/Archive/7z/7zItem.h \
530
+	7z/Archive/7z/7zHeader.c 7z/Archive/7z/7zHeader.h \
531
+	7z/Archive/7z/7zExtract.c 7z/Archive/7z/7zExtract.h explode.c \
532
+	explode.h textnorm.c textnorm.h dlp.c dlp.h jsparse/js-norm.c \
533
+	jsparse/js-norm.h jsparse/lexglobal.h jsparse/textbuf.h uniq.c \
534
+	uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \
535
+	sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \
536
+	bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \
537
+	ishield.c ishield.h $(am__append_7)
531 538
 noinst_LTLIBRARIES = libclamav_internal_utils.la libclamav_internal_utils_nothreads.la
532 539
 COMMON_CLEANFILES = version.h version.h.tmp *.gcda *.gcno
533 540
 @MAINTAINER_MODE_TRUE@BUILT_SOURCES = jsparse/generated/operators.h jsparse/generated/keywords.h jsparse-keywords.gperf
... ...
@@ -637,6 +657,20 @@ distclean-compile:
637 637
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-regfree.Plo@am__quote@
638 638
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-str.Plo@am__quote@
639 639
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-strlcpy.Plo@am__quote@
640
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7z.Plo@am__quote@
641
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zBuf.Plo@am__quote@
642
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zCrc.Plo@am__quote@
643
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zDecode.Plo@am__quote@
644
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zExtract.Plo@am__quote@
645
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zFile.Plo@am__quote@
646
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zHeader.Plo@am__quote@
647
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zIn.Plo@am__quote@
648
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zItem.Plo@am__quote@
649
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zStream.Plo@am__quote@
650
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Bcj2.Plo@am__quote@
651
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Bra.Plo@am__quote@
652
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Bra86.Plo@am__quote@
653
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-BraIA64.Plo@am__quote@
640 654
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-LzmaDec.Plo@am__quote@
641 655
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-aspack.Plo@am__quote@
642 656
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-autoit.Plo@am__quote@
... ...
@@ -1194,6 +1228,104 @@ libclamav_la-lzma_iface.lo: lzma_iface.c
1194 1194
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1195 1195
 @am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-lzma_iface.lo `test -f 'lzma_iface.c' || echo '$(srcdir)/'`lzma_iface.c
1196 1196
 
1197
+libclamav_la-7z.lo: 7z.c
1198
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7z.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7z.Tpo -c -o libclamav_la-7z.lo `test -f '7z.c' || echo '$(srcdir)/'`7z.c
1199
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7z.Tpo $(DEPDIR)/libclamav_la-7z.Plo
1200
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z.c' object='libclamav_la-7z.lo' libtool=yes @AMDEPBACKSLASH@
1201
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1202
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7z.lo `test -f '7z.c' || echo '$(srcdir)/'`7z.c
1203
+
1204
+libclamav_la-7zFile.lo: 7z/7zFile.c
1205
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zFile.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zFile.Tpo -c -o libclamav_la-7zFile.lo `test -f '7z/7zFile.c' || echo '$(srcdir)/'`7z/7zFile.c
1206
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zFile.Tpo $(DEPDIR)/libclamav_la-7zFile.Plo
1207
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/7zFile.c' object='libclamav_la-7zFile.lo' libtool=yes @AMDEPBACKSLASH@
1208
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1209
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zFile.lo `test -f '7z/7zFile.c' || echo '$(srcdir)/'`7z/7zFile.c
1210
+
1211
+libclamav_la-7zStream.lo: 7z/7zStream.c
1212
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zStream.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zStream.Tpo -c -o libclamav_la-7zStream.lo `test -f '7z/7zStream.c' || echo '$(srcdir)/'`7z/7zStream.c
1213
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zStream.Tpo $(DEPDIR)/libclamav_la-7zStream.Plo
1214
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/7zStream.c' object='libclamav_la-7zStream.lo' libtool=yes @AMDEPBACKSLASH@
1215
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1216
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zStream.lo `test -f '7z/7zStream.c' || echo '$(srcdir)/'`7z/7zStream.c
1217
+
1218
+libclamav_la-7zCrc.lo: 7z/7zCrc.c
1219
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zCrc.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zCrc.Tpo -c -o libclamav_la-7zCrc.lo `test -f '7z/7zCrc.c' || echo '$(srcdir)/'`7z/7zCrc.c
1220
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zCrc.Tpo $(DEPDIR)/libclamav_la-7zCrc.Plo
1221
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/7zCrc.c' object='libclamav_la-7zCrc.lo' libtool=yes @AMDEPBACKSLASH@
1222
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1223
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zCrc.lo `test -f '7z/7zCrc.c' || echo '$(srcdir)/'`7z/7zCrc.c
1224
+
1225
+libclamav_la-7zBuf.lo: 7z/7zBuf.c
1226
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zBuf.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zBuf.Tpo -c -o libclamav_la-7zBuf.lo `test -f '7z/7zBuf.c' || echo '$(srcdir)/'`7z/7zBuf.c
1227
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zBuf.Tpo $(DEPDIR)/libclamav_la-7zBuf.Plo
1228
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/7zBuf.c' object='libclamav_la-7zBuf.lo' libtool=yes @AMDEPBACKSLASH@
1229
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1230
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zBuf.lo `test -f '7z/7zBuf.c' || echo '$(srcdir)/'`7z/7zBuf.c
1231
+
1232
+libclamav_la-Bcj2.lo: 7z/Bcj2.c
1233
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-Bcj2.lo -MD -MP -MF $(DEPDIR)/libclamav_la-Bcj2.Tpo -c -o libclamav_la-Bcj2.lo `test -f '7z/Bcj2.c' || echo '$(srcdir)/'`7z/Bcj2.c
1234
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-Bcj2.Tpo $(DEPDIR)/libclamav_la-Bcj2.Plo
1235
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Bcj2.c' object='libclamav_la-Bcj2.lo' libtool=yes @AMDEPBACKSLASH@
1236
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1237
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-Bcj2.lo `test -f '7z/Bcj2.c' || echo '$(srcdir)/'`7z/Bcj2.c
1238
+
1239
+libclamav_la-Bra.lo: 7z/Bra.c
1240
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-Bra.lo -MD -MP -MF $(DEPDIR)/libclamav_la-Bra.Tpo -c -o libclamav_la-Bra.lo `test -f '7z/Bra.c' || echo '$(srcdir)/'`7z/Bra.c
1241
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-Bra.Tpo $(DEPDIR)/libclamav_la-Bra.Plo
1242
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Bra.c' object='libclamav_la-Bra.lo' libtool=yes @AMDEPBACKSLASH@
1243
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1244
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-Bra.lo `test -f '7z/Bra.c' || echo '$(srcdir)/'`7z/Bra.c
1245
+
1246
+libclamav_la-Bra86.lo: 7z/Bra86.c
1247
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-Bra86.lo -MD -MP -MF $(DEPDIR)/libclamav_la-Bra86.Tpo -c -o libclamav_la-Bra86.lo `test -f '7z/Bra86.c' || echo '$(srcdir)/'`7z/Bra86.c
1248
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-Bra86.Tpo $(DEPDIR)/libclamav_la-Bra86.Plo
1249
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Bra86.c' object='libclamav_la-Bra86.lo' libtool=yes @AMDEPBACKSLASH@
1250
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1251
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-Bra86.lo `test -f '7z/Bra86.c' || echo '$(srcdir)/'`7z/Bra86.c
1252
+
1253
+libclamav_la-BraIA64.lo: 7z/BraIA64.c
1254
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-BraIA64.lo -MD -MP -MF $(DEPDIR)/libclamav_la-BraIA64.Tpo -c -o libclamav_la-BraIA64.lo `test -f '7z/BraIA64.c' || echo '$(srcdir)/'`7z/BraIA64.c
1255
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-BraIA64.Tpo $(DEPDIR)/libclamav_la-BraIA64.Plo
1256
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/BraIA64.c' object='libclamav_la-BraIA64.lo' libtool=yes @AMDEPBACKSLASH@
1257
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1258
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-BraIA64.lo `test -f '7z/BraIA64.c' || echo '$(srcdir)/'`7z/BraIA64.c
1259
+
1260
+libclamav_la-7zIn.lo: 7z/Archive/7z/7zIn.c
1261
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zIn.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zIn.Tpo -c -o libclamav_la-7zIn.lo `test -f '7z/Archive/7z/7zIn.c' || echo '$(srcdir)/'`7z/Archive/7z/7zIn.c
1262
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zIn.Tpo $(DEPDIR)/libclamav_la-7zIn.Plo
1263
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Archive/7z/7zIn.c' object='libclamav_la-7zIn.lo' libtool=yes @AMDEPBACKSLASH@
1264
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1265
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zIn.lo `test -f '7z/Archive/7z/7zIn.c' || echo '$(srcdir)/'`7z/Archive/7z/7zIn.c
1266
+
1267
+libclamav_la-7zDecode.lo: 7z/Archive/7z/7zDecode.c
1268
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zDecode.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zDecode.Tpo -c -o libclamav_la-7zDecode.lo `test -f '7z/Archive/7z/7zDecode.c' || echo '$(srcdir)/'`7z/Archive/7z/7zDecode.c
1269
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zDecode.Tpo $(DEPDIR)/libclamav_la-7zDecode.Plo
1270
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Archive/7z/7zDecode.c' object='libclamav_la-7zDecode.lo' libtool=yes @AMDEPBACKSLASH@
1271
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1272
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zDecode.lo `test -f '7z/Archive/7z/7zDecode.c' || echo '$(srcdir)/'`7z/Archive/7z/7zDecode.c
1273
+
1274
+libclamav_la-7zItem.lo: 7z/Archive/7z/7zItem.c
1275
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zItem.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zItem.Tpo -c -o libclamav_la-7zItem.lo `test -f '7z/Archive/7z/7zItem.c' || echo '$(srcdir)/'`7z/Archive/7z/7zItem.c
1276
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zItem.Tpo $(DEPDIR)/libclamav_la-7zItem.Plo
1277
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Archive/7z/7zItem.c' object='libclamav_la-7zItem.lo' libtool=yes @AMDEPBACKSLASH@
1278
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1279
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zItem.lo `test -f '7z/Archive/7z/7zItem.c' || echo '$(srcdir)/'`7z/Archive/7z/7zItem.c
1280
+
1281
+libclamav_la-7zHeader.lo: 7z/Archive/7z/7zHeader.c
1282
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zHeader.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zHeader.Tpo -c -o libclamav_la-7zHeader.lo `test -f '7z/Archive/7z/7zHeader.c' || echo '$(srcdir)/'`7z/Archive/7z/7zHeader.c
1283
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zHeader.Tpo $(DEPDIR)/libclamav_la-7zHeader.Plo
1284
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Archive/7z/7zHeader.c' object='libclamav_la-7zHeader.lo' libtool=yes @AMDEPBACKSLASH@
1285
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1286
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zHeader.lo `test -f '7z/Archive/7z/7zHeader.c' || echo '$(srcdir)/'`7z/Archive/7z/7zHeader.c
1287
+
1288
+libclamav_la-7zExtract.lo: 7z/Archive/7z/7zExtract.c
1289
+@am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zExtract.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zExtract.Tpo -c -o libclamav_la-7zExtract.lo `test -f '7z/Archive/7z/7zExtract.c' || echo '$(srcdir)/'`7z/Archive/7z/7zExtract.c
1290
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-7zExtract.Tpo $(DEPDIR)/libclamav_la-7zExtract.Plo
1291
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='7z/Archive/7z/7zExtract.c' object='libclamav_la-7zExtract.lo' libtool=yes @AMDEPBACKSLASH@
1292
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1293
+@am__fastdepCC_FALSE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zExtract.lo `test -f '7z/Archive/7z/7zExtract.c' || echo '$(srcdir)/'`7z/Archive/7z/7zExtract.c
1294
+
1197 1295
 libclamav_la-explode.lo: explode.c
1198 1296
 @am__fastdepCC_TRUE@	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-explode.lo -MD -MP -MF $(DEPDIR)/libclamav_la-explode.Tpo -c -o libclamav_la-explode.lo `test -f 'explode.c' || echo '$(srcdir)/'`explode.c
1199 1297
 @am__fastdepCC_TRUE@	mv -f $(DEPDIR)/libclamav_la-explode.Tpo $(DEPDIR)/libclamav_la-explode.Plo
... ...
@@ -91,6 +91,7 @@ static struct dconf_module modules[] = {
91 91
     { "ARCHIVE",    "NSIS",	    ARCH_CONF_NSIS,	    1 },
92 92
     { "ARCHIVE",    "AUTOIT",	    ARCH_CONF_AUTOIT,	    1 },
93 93
     { "ARCHIVE",    "ISHIELD",	    ARCH_CONF_ISHIELD,	    1 },
94
+    { "ARCHIVE",    "7zip",	    ARCH_CONF_7Z,	    1 },
94 95
 
95 96
     { "DOCUMENT",   "HTML",	    DOC_CONF_HTML,	    1 },
96 97
     { "DOCUMENT",   "RTF",	    DOC_CONF_RTF,	    1 },
... ...
@@ -76,6 +76,7 @@ struct cli_dconf {
76 76
 #define ARCH_CONF_AUTOIT    0x2000
77 77
 #define ARCH_CONF_CPIO	    0x4000
78 78
 #define ARCH_CONF_ISHIELD   0x8000
79
+#define ARCH_CONF_7Z        0x10000
79 80
 
80 81
 /* Document flags */
81 82
 #define DOC_CONF_HTML		0x1
... ...
@@ -95,6 +95,7 @@ static const struct ftmap_s {
95 95
     { "CL_TYPE_NULSFT",		CL_TYPE_NULSFT		},
96 96
     { "CL_TYPE_AUTOIT",		CL_TYPE_AUTOIT		},
97 97
     { "CL_TYPE_ISHIELD_MSI",	CL_TYPE_ISHIELD_MSI	},
98
+    { "CL_TYPE_7Z",		CL_TYPE_7Z		},
98 99
     { NULL,			CL_TYPE_IGNORED		}
99 100
 };
100 101
 
... ...
@@ -70,6 +70,7 @@ typedef enum {
70 70
     CL_TYPE_SCRIPT,
71 71
     CL_TYPE_HTML_UTF16,
72 72
     CL_TYPE_RTF,
73
+    CL_TYPE_7Z,
73 74
 
74 75
     /* bigger numbers have higher priority (in o-t-f detection) */
75 76
     CL_TYPE_HTML, /* on the fly */
... ...
@@ -149,6 +149,7 @@ static const char *ftypes_int[] = {
149 149
   "0:0:feedface:Mach-O BE:CL_TYPE_ANY:CL_TYPE_MACHO:45",
150 150
   "0:0:feedfacf:Mach-O BE 64-bit:CL_TYPE_ANY:CL_TYPE_MACHO:45",
151 151
   "1:*:496e7374616c6c536869656c6400{292}0600000000000000{8}0000000001:ISHIELD-MSI:CL_TYPE_ANY:CL_TYPE_ISHIELD_MSI:45",
152
+  "0:0:377abcaf271c:7zip:CL_TYPE_ANY:CL_TYPE_7Z:47",
152 153
   "0:0:cafebabe:Universal Binary/Java Bytecode:CL_TYPE_ANY:CL_TYPE_MACHO_UNIBIN:46",
153 154
   NULL
154 155
 };
... ...
@@ -26,15 +26,15 @@
26 26
 
27 27
 #include "lzma_iface.h"
28 28
 
29
-static void *__wrap_alloc(void *unused, size_t size) { 
29
+void *__lzma_wrap_alloc(void *unused, size_t size) { 
30 30
     unused = unused;
31 31
     return cli_malloc(size);
32 32
 }
33
-static void __wrap_free(void *unused, void *freeme) {
33
+void __lzma_wrap_free(void *unused, void *freeme) {
34 34
     unused = unused;
35 35
     free(freeme);
36 36
 }
37
-static ISzAlloc g_Alloc = { __wrap_alloc, __wrap_free };
37
+static ISzAlloc g_Alloc = { __lzma_wrap_alloc, __lzma_wrap_free };
38 38
 
39 39
 
40 40
 static unsigned char lzma_getbyte(struct CLI_LZMA *L, int *fail) {
... ...
@@ -53,6 +53,9 @@ int cli_LzmaInit(struct CLI_LZMA *, uint64_t);
53 53
 void cli_LzmaShutdown(struct CLI_LZMA *);
54 54
 int cli_LzmaDecode(struct CLI_LZMA *);
55 55
 
56
+void *__lzma_wrap_alloc(void *unused, size_t size);
57
+void __lzma_wrap_free(void *unused, void *freeme);
58
+
56 59
 #define LZMA_STREAM_END 2
57 60
 #define LZMA_RESULT_OK 0
58 61
 #define LZMA_RESULT_DATA_ERROR 1
... ...
@@ -49,7 +49,7 @@
49 49
  * in re-enabling affected modules.
50 50
  */
51 51
 
52
-#define CL_FLEVEL 46
52
+#define CL_FLEVEL 47
53 53
 #define CL_FLEVEL_DCONF	CL_FLEVEL
54 54
 
55 55
 extern uint8_t cli_debug_flag;
... ...
@@ -95,6 +95,7 @@
95 95
 #include "cpio.h"
96 96
 #include "macho.h"
97 97
 #include "ishield.h"
98
+#include "7z.h"
98 99
 
99 100
 #ifdef HAVE_BZLIB_H
100 101
 #include <bzlib.h>
... ...
@@ -2028,6 +2029,11 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2028 2028
 		ret = cli_scanole2(desc, ctx);
2029 2029
 	    break;
2030 2030
 
2031
+	case CL_TYPE_7Z:
2032
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z))
2033
+		ret = cli_7unz(desc, ctx);
2034
+	    break;
2035
+
2031 2036
 	case CL_TYPE_POSIX_TAR:
2032 2037
 	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR))
2033 2038
 		ret = cli_scantar(desc, ctx, 1);