1 /* Lzma2Dec.c -- LZMA2 Decoder
2 2010-12-15 : Igor Pavlov : Public domain */
3 
4 /* #define SHOW_DEBUG_INFO */
5 
6 #include "Precomp.h"
7 
8 #ifdef SHOW_DEBUG_INFO
9 #include <stdio.h>
10 #endif
11 
12 #include <string.h>
13 
14 #include "Lzma2Dec.h"
15 
16 /*
17 00000000  -  EOS
18 00000001 U U  -  Uncompressed Reset Dic
19 00000010 U U  -  Uncompressed No Reset
20 100uuuuu U U P P  -  LZMA no reset
21 101uuuuu U U P P  -  LZMA reset state
22 110uuuuu U U P P S  -  LZMA reset state + new prop
23 111uuuuu U U P P S  -  LZMA reset state + new prop + reset dic
24 
25   u, U - Unpack Size
26   P - Pack Size
27   S - Props
28 */
29 
30 #define LZMA2_CONTROL_LZMA (1 << 7)
31 #define LZMA2_CONTROL_COPY_NO_RESET 2
32 #define LZMA2_CONTROL_COPY_RESET_DIC 1
33 #define LZMA2_CONTROL_EOF 0
34 
35 #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
36 
37 #define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
38 #define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
39 
40 #define LZMA2_LCLP_MAX 4
41 #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
42 
43 #ifdef SHOW_DEBUG_INFO
44 #define PRF(x) x
45 #else
46 #define PRF(x)
47 #endif
48 
49 typedef enum
50 {
51   LZMA2_STATE_CONTROL,
52   LZMA2_STATE_UNPACK0,
53   LZMA2_STATE_UNPACK1,
54   LZMA2_STATE_PACK0,
55   LZMA2_STATE_PACK1,
56   LZMA2_STATE_PROP,
57   LZMA2_STATE_DATA,
58   LZMA2_STATE_DATA_CONT,
59   LZMA2_STATE_FINISHED,
60   LZMA2_STATE_ERROR
61 } ELzma2State;
62 
Lzma2Dec_GetOldProps(Byte prop,Byte * props)63 static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
64 {
65   UInt32 dicSize;
66   if (prop > 40)
67     return SZ_ERROR_UNSUPPORTED;
68   dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
69   props[0] = (Byte)LZMA2_LCLP_MAX;
70   props[1] = (Byte)(dicSize);
71   props[2] = (Byte)(dicSize >> 8);
72   props[3] = (Byte)(dicSize >> 16);
73   props[4] = (Byte)(dicSize >> 24);
74   return SZ_OK;
75 }
76 
Lzma2Dec_AllocateProbs(CLzma2Dec * p,Byte prop,ISzAlloc * alloc)77 SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
78 {
79   Byte props[LZMA_PROPS_SIZE];
80   RINOK(Lzma2Dec_GetOldProps(prop, props));
81   return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
82 }
83 
Lzma2Dec_Allocate(CLzma2Dec * p,Byte prop,ISzAlloc * alloc)84 SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
85 {
86   Byte props[LZMA_PROPS_SIZE];
87   RINOK(Lzma2Dec_GetOldProps(prop, props));
88   return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
89 }
90 
Lzma2Dec_Init(CLzma2Dec * p)91 void Lzma2Dec_Init(CLzma2Dec *p)
92 {
93   p->state = LZMA2_STATE_CONTROL;
94   p->needInitDic = True;
95   p->needInitState = True;
96   p->needInitProp = True;
97   LzmaDec_Init(&p->decoder);
98 }
99 
Lzma2Dec_UpdateState(CLzma2Dec * p,Byte b)100 static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
101 {
102   switch(p->state)
103   {
104     case LZMA2_STATE_CONTROL:
105       p->control = b;
106       PRF(printf("\n %4X ", p->decoder.dicPos));
107       PRF(printf(" %2X", b));
108       if (p->control == 0)
109         return LZMA2_STATE_FINISHED;
110       if (LZMA2_IS_UNCOMPRESSED_STATE(p))
111       {
112         if ((p->control & 0x7F) > 2)
113           return LZMA2_STATE_ERROR;
114         p->unpackSize = 0;
115       }
116       else
117         p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
118       return LZMA2_STATE_UNPACK0;
119 
120     case LZMA2_STATE_UNPACK0:
121       p->unpackSize |= (UInt32)b << 8;
122       return LZMA2_STATE_UNPACK1;
123 
124     case LZMA2_STATE_UNPACK1:
125       p->unpackSize |= (UInt32)b;
126       p->unpackSize++;
127       PRF(printf(" %8d", p->unpackSize));
128       return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
129 
130     case LZMA2_STATE_PACK0:
131       p->packSize = (UInt32)b << 8;
132       return LZMA2_STATE_PACK1;
133 
134     case LZMA2_STATE_PACK1:
135       p->packSize |= (UInt32)b;
136       p->packSize++;
137       PRF(printf(" %8d", p->packSize));
138       return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
139         (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
140 
141     case LZMA2_STATE_PROP:
142     {
143       int lc, lp;
144       if (b >= (9 * 5 * 5))
145         return LZMA2_STATE_ERROR;
146       lc = b % 9;
147       b /= 9;
148       p->decoder.prop.pb = b / 5;
149       lp = b % 5;
150       if (lc + lp > LZMA2_LCLP_MAX)
151         return LZMA2_STATE_ERROR;
152       p->decoder.prop.lc = lc;
153       p->decoder.prop.lp = lp;
154       p->needInitProp = False;
155       return LZMA2_STATE_DATA;
156     }
157   }
158   return LZMA2_STATE_ERROR;
159 }
160 
LzmaDec_UpdateWithUncompressed(CLzmaDec * p,const Byte * src,SizeT size)161 static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
162 {
163   memcpy(p->dic + p->dicPos, src, size);
164   p->dicPos += size;
165   if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
166     p->checkDicSize = p->prop.dicSize;
167   p->processedPos += (UInt32)size;
168 }
169 
170 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
171 
Lzma2Dec_DecodeToDic(CLzma2Dec * p,SizeT dicLimit,const Byte * src,SizeT * srcLen,ELzmaFinishMode finishMode,ELzmaStatus * status)172 SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
173     const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
174 {
175   SizeT inSize = *srcLen;
176   *srcLen = 0;
177   *status = LZMA_STATUS_NOT_SPECIFIED;
178 
179   while (p->state != LZMA2_STATE_FINISHED)
180   {
181     SizeT dicPos = p->decoder.dicPos;
182     if (p->state == LZMA2_STATE_ERROR)
183       return SZ_ERROR_DATA;
184     if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
185     {
186       *status = LZMA_STATUS_NOT_FINISHED;
187       return SZ_OK;
188     }
189     if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
190     {
191       if (*srcLen == inSize)
192       {
193         *status = LZMA_STATUS_NEEDS_MORE_INPUT;
194         return SZ_OK;
195       }
196       (*srcLen)++;
197       p->state = Lzma2Dec_UpdateState(p, *src++);
198       continue;
199     }
200     {
201       SizeT destSizeCur = dicLimit - dicPos;
202       SizeT srcSizeCur = inSize - *srcLen;
203       ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
204 
205       if (p->unpackSize <= destSizeCur)
206       {
207         destSizeCur = (SizeT)p->unpackSize;
208         curFinishMode = LZMA_FINISH_END;
209       }
210 
211       if (LZMA2_IS_UNCOMPRESSED_STATE(p))
212       {
213         if (*srcLen == inSize)
214         {
215           *status = LZMA_STATUS_NEEDS_MORE_INPUT;
216           return SZ_OK;
217         }
218 
219         if (p->state == LZMA2_STATE_DATA)
220         {
221           Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
222           if (initDic)
223             p->needInitProp = p->needInitState = True;
224           else if (p->needInitDic)
225             return SZ_ERROR_DATA;
226           p->needInitDic = False;
227           LzmaDec_InitDicAndState(&p->decoder, initDic, False);
228         }
229 
230         if (srcSizeCur > destSizeCur)
231           srcSizeCur = destSizeCur;
232 
233         if (srcSizeCur == 0)
234           return SZ_ERROR_DATA;
235 
236         LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
237 
238         src += srcSizeCur;
239         *srcLen += srcSizeCur;
240         p->unpackSize -= (UInt32)srcSizeCur;
241         p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
242       }
243       else
244       {
245         SizeT outSizeProcessed;
246         SRes res;
247 
248         if (p->state == LZMA2_STATE_DATA)
249         {
250           int mode = LZMA2_GET_LZMA_MODE(p);
251           Bool initDic = (mode == 3);
252           Bool initState = (mode > 0);
253           if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
254             return SZ_ERROR_DATA;
255 
256           LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
257           p->needInitDic = False;
258           p->needInitState = False;
259           p->state = LZMA2_STATE_DATA_CONT;
260         }
261         if (srcSizeCur > p->packSize)
262           srcSizeCur = (SizeT)p->packSize;
263 
264         res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
265 
266         src += srcSizeCur;
267         *srcLen += srcSizeCur;
268         p->packSize -= (UInt32)srcSizeCur;
269 
270         outSizeProcessed = p->decoder.dicPos - dicPos;
271         p->unpackSize -= (UInt32)outSizeProcessed;
272 
273         RINOK(res);
274         if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
275           return res;
276 
277         if (srcSizeCur == 0 && outSizeProcessed == 0)
278         {
279           if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
280               p->unpackSize != 0 || p->packSize != 0)
281             return SZ_ERROR_DATA;
282           p->state = LZMA2_STATE_CONTROL;
283         }
284         if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
285           *status = LZMA_STATUS_NOT_FINISHED;
286       }
287     }
288   }
289   *status = LZMA_STATUS_FINISHED_WITH_MARK;
290   return SZ_OK;
291 }
292 
Lzma2Dec_DecodeToBuf(CLzma2Dec * p,Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,ELzmaFinishMode finishMode,ELzmaStatus * status)293 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
294 {
295   SizeT outSize = *destLen, inSize = *srcLen;
296   *srcLen = *destLen = 0;
297   for (;;)
298   {
299     SizeT srcSizeCur = inSize, outSizeCur, dicPos;
300     ELzmaFinishMode curFinishMode;
301     SRes res;
302     if (p->decoder.dicPos == p->decoder.dicBufSize)
303       p->decoder.dicPos = 0;
304     dicPos = p->decoder.dicPos;
305     if (outSize > p->decoder.dicBufSize - dicPos)
306     {
307       outSizeCur = p->decoder.dicBufSize;
308       curFinishMode = LZMA_FINISH_ANY;
309     }
310     else
311     {
312       outSizeCur = dicPos + outSize;
313       curFinishMode = finishMode;
314     }
315 
316     res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
317     src += srcSizeCur;
318     inSize -= srcSizeCur;
319     *srcLen += srcSizeCur;
320     outSizeCur = p->decoder.dicPos - dicPos;
321     memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
322     dest += outSizeCur;
323     outSize -= outSizeCur;
324     *destLen += outSizeCur;
325     if (res != 0)
326       return res;
327     if (outSizeCur == 0 || outSize == 0)
328       return SZ_OK;
329   }
330 }
331 
Lzma2Decode(Byte * dest,SizeT * destLen,const Byte * src,SizeT * srcLen,Byte prop,ELzmaFinishMode finishMode,ELzmaStatus * status,ISzAlloc * alloc)332 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
333     Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
334 {
335   CLzma2Dec p;
336   SRes res;
337   SizeT outSize = *destLen, inSize = *srcLen;
338   *destLen = *srcLen = 0;
339   *status = LZMA_STATUS_NOT_SPECIFIED;
340   Lzma2Dec_Construct(&p);
341   RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
342   p.decoder.dic = dest;
343   p.decoder.dicBufSize = outSize;
344   Lzma2Dec_Init(&p);
345   *srcLen = inSize;
346   res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
347   *destLen = p.decoder.dicPos;
348   if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
349     res = SZ_ERROR_INPUT_EOF;
350   Lzma2Dec_FreeProbs(&p, alloc);
351   return res;
352 }
353