~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/7z/Archive/7z/7zDecode.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 7zDecode.c -- Decoding from 7z folder
 
2
2008-11-23 : Igor Pavlov : Public domain */
 
3
 
 
4
#include <string.h>
 
5
 
 
6
#include "../../Bcj2.h"
 
7
#include "../../Bra.h"
 
8
#include "../../LzmaDec.h"
 
9
#include "7zDecode.h"
 
10
 
 
11
#define k_Copy 0
 
12
#define k_LZMA 0x30101
 
13
#define k_BCJ 0x03030103
 
14
#define k_BCJ2 0x0303011B
 
15
 
 
16
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
 
17
    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
 
18
{
 
19
  CLzmaDec state;
 
20
  SRes res = SZ_OK;
 
21
 
 
22
  LzmaDec_Construct(&state);
 
23
  RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
 
24
  state.dic = outBuffer;
 
25
  state.dicBufSize = outSize;
 
26
  LzmaDec_Init(&state);
 
27
 
 
28
  for (;;)
 
29
  {
 
30
    Byte *inBuf = NULL;
 
31
    size_t lookahead = (1 << 18);
 
32
    if (lookahead > inSize)
 
33
      lookahead = (size_t)inSize;
 
34
    res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
 
35
    if (res != SZ_OK)
 
36
      break;
 
37
 
 
38
    {
 
39
      SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
 
40
      ELzmaStatus status;
 
41
      res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
 
42
      lookahead -= inProcessed;
 
43
      inSize -= inProcessed;
 
44
      if (res != SZ_OK)
 
45
        break;
 
46
      if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
 
47
      {
 
48
        if (state.dicBufSize != outSize || lookahead != 0 ||
 
49
            (status != LZMA_STATUS_FINISHED_WITH_MARK &&
 
50
             status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
 
51
          res = SZ_ERROR_DATA;
 
52
        break;
 
53
      }
 
54
      res = inStream->Skip((void *)inStream, inProcessed);
 
55
      if (res != SZ_OK)
 
56
        break;
 
57
    }
 
58
  }
 
59
 
 
60
  LzmaDec_FreeProbs(&state, allocMain);
 
61
  return res;
 
62
}
 
63
 
 
64
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
 
65
{
 
66
  while (inSize > 0)
 
67
  {
 
68
    void *inBuf;
 
69
    size_t curSize = (1 << 18);
 
70
    if (curSize > inSize)
 
71
      curSize = (size_t)inSize;
 
72
    RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
 
73
    if (curSize == 0)
 
74
      return SZ_ERROR_INPUT_EOF;
 
75
    memcpy(outBuffer, inBuf, curSize);
 
76
    outBuffer += curSize;
 
77
    inSize -= curSize;
 
78
    RINOK(inStream->Skip((void *)inStream, curSize));
 
79
  }
 
80
  return SZ_OK;
 
81
}
 
82
 
 
83
#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
 
84
#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
 
85
#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
 
86
#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
 
87
 
 
88
SRes CheckSupportedFolder(const CSzFolder *f)
 
89
{
 
90
  if (f->NumCoders < 1 || f->NumCoders > 4)
 
91
    return SZ_ERROR_UNSUPPORTED;
 
92
  if (IS_UNSUPPORTED_CODER(f->Coders[0]))
 
93
    return SZ_ERROR_UNSUPPORTED;
 
94
  if (f->NumCoders == 1)
 
95
  {
 
96
    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
 
97
      return SZ_ERROR_UNSUPPORTED;
 
98
    return SZ_OK;
 
99
  }
 
100
  if (f->NumCoders == 2)
 
101
  {
 
102
    if (IS_NO_BCJ(f->Coders[1]) ||
 
103
        f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
 
104
        f->NumBindPairs != 1 ||
 
105
        f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
 
106
      return SZ_ERROR_UNSUPPORTED;
 
107
    return SZ_OK;
 
108
  }
 
109
  if (f->NumCoders == 4)
 
110
  {
 
111
    if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
 
112
        IS_UNSUPPORTED_CODER(f->Coders[2]) ||
 
113
        IS_NO_BCJ2(f->Coders[3]))
 
114
      return SZ_ERROR_UNSUPPORTED;
 
115
    if (f->NumPackStreams != 4 ||
 
116
        f->PackStreams[0] != 2 ||
 
117
        f->PackStreams[1] != 6 ||
 
118
        f->PackStreams[2] != 1 ||
 
119
        f->PackStreams[3] != 0 ||
 
120
        f->NumBindPairs != 3 ||
 
121
        f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
 
122
        f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
 
123
        f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
 
124
      return SZ_ERROR_UNSUPPORTED;
 
125
    return SZ_OK;
 
126
  }
 
127
  return SZ_ERROR_UNSUPPORTED;
 
128
}
 
129
 
 
130
UInt64 GetSum(const UInt64 *values, UInt32 index)
 
131
{
 
132
  UInt64 sum = 0;
 
133
  UInt32 i;
 
134
  for (i = 0; i < index; i++)
 
135
    sum += values[i];
 
136
  return sum;
 
137
}
 
138
 
 
139
SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
 
140
    ILookInStream *inStream, UInt64 startPos,
 
141
    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
 
142
    Byte *tempBuf[])
 
143
{
 
144
  UInt32 ci;
 
145
  SizeT tempSizes[3] = { 0, 0, 0};
 
146
  SizeT tempSize3 = 0;
 
147
  Byte *tempBuf3 = 0;
 
148
 
 
149
  RINOK(CheckSupportedFolder(folder));
 
150
 
 
151
  for (ci = 0; ci < folder->NumCoders; ci++)
 
152
  {
 
153
    CSzCoderInfo *coder = &folder->Coders[ci];
 
154
 
 
155
    if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
 
156
    {
 
157
      UInt32 si = 0;
 
158
      UInt64 offset;
 
159
      UInt64 inSize;
 
160
      Byte *outBufCur = outBuffer;
 
161
      SizeT outSizeCur = outSize;
 
162
      if (folder->NumCoders == 4)
 
163
      {
 
164
        UInt32 indices[] = { 3, 2, 0 };
 
165
        UInt64 unpackSize = folder->UnpackSizes[ci];
 
166
        si = indices[ci];
 
167
        if (ci < 2)
 
168
        {
 
169
          Byte *temp;
 
170
          outSizeCur = (SizeT)unpackSize;
 
171
          if (outSizeCur != unpackSize)
 
172
            return SZ_ERROR_MEM;
 
173
          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
 
174
          if (temp == 0 && outSizeCur != 0)
 
175
            return SZ_ERROR_MEM;
 
176
          outBufCur = tempBuf[1 - ci] = temp;
 
177
          tempSizes[1 - ci] = outSizeCur;
 
178
        }
 
179
        else if (ci == 2)
 
180
        {
 
181
          if (unpackSize > outSize) /* check it */
 
182
            return SZ_ERROR_PARAM;
 
183
          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
 
184
          tempSize3 = outSizeCur = (SizeT)unpackSize;
 
185
        }
 
186
        else
 
187
          return SZ_ERROR_UNSUPPORTED;
 
188
      }
 
189
      offset = GetSum(packSizes, si);
 
190
      inSize = packSizes[si];
 
191
      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
 
192
 
 
193
      if (coder->MethodID == k_Copy)
 
194
      {
 
195
        if (inSize != outSizeCur) /* check it */
 
196
          return SZ_ERROR_DATA;
 
197
        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
 
198
      }
 
199
      else
 
200
      {
 
201
        RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
 
202
      }
 
203
    }
 
204
    else if (coder->MethodID == k_BCJ)
 
205
    {
 
206
      UInt32 state;
 
207
      if (ci != 1)
 
208
        return SZ_ERROR_UNSUPPORTED;
 
209
      x86_Convert_Init(state);
 
210
      x86_Convert(outBuffer, outSize, 0, &state, 0);
 
211
    }
 
212
    else if (coder->MethodID == k_BCJ2)
 
213
    {
 
214
      UInt64 offset = GetSum(packSizes, 1);
 
215
      UInt64 s3Size = packSizes[1];
 
216
      SRes res;
 
217
      if (ci != 3)
 
218
        return SZ_ERROR_UNSUPPORTED;
 
219
      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
 
220
      tempSizes[2] = (SizeT)s3Size;
 
221
      if (tempSizes[2] != s3Size)
 
222
        return SZ_ERROR_MEM;
 
223
      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
 
224
      if (tempBuf[2] == 0 && tempSizes[2] != 0)
 
225
        return SZ_ERROR_MEM;
 
226
      res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
 
227
      RINOK(res)
 
228
 
 
229
      res = Bcj2_Decode(
 
230
          tempBuf3, tempSize3,
 
231
          tempBuf[0], tempSizes[0],
 
232
          tempBuf[1], tempSizes[1],
 
233
          tempBuf[2], tempSizes[2],
 
234
          outBuffer, outSize);
 
235
      RINOK(res)
 
236
    }
 
237
    else
 
238
      return SZ_ERROR_UNSUPPORTED;
 
239
  }
 
240
  return SZ_OK;
 
241
}
 
242
 
 
243
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
 
244
    ILookInStream *inStream, UInt64 startPos,
 
245
    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
 
246
{
 
247
  Byte *tempBuf[3] = { 0, 0, 0};
 
248
  int i;
 
249
  SRes res = SzDecode2(packSizes, folder, inStream, startPos,
 
250
      outBuffer, (SizeT)outSize, allocMain, tempBuf);
 
251
  for (i = 0; i < 3; i++)
 
252
    IAlloc_Free(allocMain, tempBuf[i]);
 
253
  return res;
 
254
}