blob: 2f6fa8516bcd71a09ad3e19cc56721008590d27e [file] [log] [blame]
Luc Verhaegen462b7762009-06-10 16:56:26 +02001/*
2 * This file is a severely cut down and cleaned up version of lha.
3 *
4 * All changes compared to lha-svn894 are:
5 *
6 * Copyright 2009 Luc Verhaegen <libv@skynet.be>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22/*
23 * LHA has a terrible history... It dates back to 1988, has had many different
24 * authors and has been mostly Public Domain Software.
25 *
26 * Since 1999, Koji Arai <arai@users.sourceforge.jp> has been doing most of
27 * the work at http://sourceforge.jp/projects/lha/.
28 */
29
Luc Verhaegen2e424062009-06-16 08:02:13 +020030#define _GNU_SOURCE 1
31
Luc Verhaegen462b7762009-06-10 16:56:26 +020032#include <stdio.h>
Luc Verhaegen462b7762009-06-10 16:56:26 +020033#include <string.h>
34#include <stdlib.h>
Stefan Reinauer6ed57e52010-04-24 01:15:17 +020035#include "compat.h"
Luc Verhaegen1646a412009-06-16 08:22:14 +020036#include "lh5_extract.h"
Luc Verhaegen462b7762009-06-10 16:56:26 +020037
Luc Verhaegen462b7762009-06-10 16:56:26 +020038/*
Luc Verhaegen462b7762009-06-10 16:56:26 +020039 * LHA header parsing.
Luc Verhaegen462b7762009-06-10 16:56:26 +020040 */
Anton Kochkov8f9427f2013-04-07 13:20:30 +040041static int calc_sum(unsigned char *p, int len)
Luc Verhaegen462b7762009-06-10 16:56:26 +020042{
Anton Kochkov8f9427f2013-04-07 13:20:30 +040043 int sum = 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +020044
Anton Kochkov8f9427f2013-04-07 13:20:30 +040045 while (len--)
46 sum += *p++;
Luc Verhaegen462b7762009-06-10 16:56:26 +020047
Anton Kochkov8f9427f2013-04-07 13:20:30 +040048 return sum & 0xff;
Luc Verhaegen462b7762009-06-10 16:56:26 +020049}
50
Luc Verhaegen462b7762009-06-10 16:56:26 +020051/*
52 * level 1 header
53 *
54 *
55 * offset size field name
56 * -----------------------------------
57 * 0 1 header size [*1]
58 * 1 1 header sum
59 * -------------------------------------
60 * 2 5 method ID ^
61 * 7 4 skip size [*2] |
62 * 11 4 original size |
63 * 15 2 time |
64 * 17 2 date |
65 * 19 1 attribute (0x20 fixed) | [*1] header size (X+Y+25)
66 * 20 1 level (0x01 fixed) |
67 * 21 1 name length |
68 * 22 X filename |
69 * X+ 22 2 file crc (CRC-16) |
70 * X+ 24 1 OS ID |
71 * X +25 Y ??? |
72 * X+Y+25 2 next-header size v
73 * -------------------------------------------------
74 * X+Y+27 Z ext-header ^
75 * : |
76 * ----------------------------------- | [*2] skip size
77 * X+Y+Z+27 data |
78 * : v
79 * -------------------------------------------------
80 *
81 */
Luc Verhaegen1646a412009-06-16 08:22:14 +020082unsigned int
Luc Verhaegen2e424062009-06-16 08:02:13 +020083LH5HeaderParse(unsigned char *Buffer, int BufferSize,
84 unsigned int *original_size, unsigned int *packed_size,
85 char **name, unsigned short *crc)
Luc Verhaegen462b7762009-06-10 16:56:26 +020086{
Anton Kochkov8f9427f2013-04-07 13:20:30 +040087 unsigned int offset;
88 unsigned char header_size, checksum, name_length;
Luc Verhaegen462b7762009-06-10 16:56:26 +020089
Anton Kochkov8f9427f2013-04-07 13:20:30 +040090 if (BufferSize < 27) {
91 fprintf(stderr,
92 "Error: Packed Buffer is too small to contain an lha header.\n");
93 return 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +020094 }
Luc Verhaegen462b7762009-06-10 16:56:26 +020095
Anton Kochkov8f9427f2013-04-07 13:20:30 +040096 /* check attribute */
97 if (Buffer[19] != 0x20) {
98 fprintf(stderr, "Error: Invalid lha header attribute byte.\n");
99 return 0;
100 }
101
102 /* check method */
103 if (memcmp(Buffer + 2, "-lh5-", 5) != 0) {
104 fprintf(stderr, "Error: Compression method is not LZHUFF5.\n");
105 return 0;
106 }
107
108 /* check header level */
109 if (Buffer[20] != 1) {
110 fprintf(stderr, "Error: Header level %d is not supported\n",
111 Buffer[20]);
112 return 0;
113 }
114
115 /* read in the full header */
116 header_size = Buffer[0];
117 if (BufferSize < (header_size + 2)) {
118 fprintf(stderr,
119 "Error: Packed Buffer is too small to contain the full header.\n");
120 return 0;
121 }
122
123 /* verify checksum */
124 checksum = Buffer[1];
125 if (calc_sum(Buffer + 2, header_size) != checksum) {
126 fprintf(stderr, "Error: Invalid lha header checksum.\n");
127 return 0;
128 }
129
130 *packed_size = le32toh(*(unsigned int *)(Buffer + 7));
131 *original_size = le32toh(*(unsigned int *)(Buffer + 11));
132
133 name_length = Buffer[21];
134 *name = strndup((char *)Buffer + 22, name_length);
135
136 *crc = le16toh(*(unsigned short *)(Buffer + 22 + name_length));
137
138 offset = header_size + 2;
139 /* Skip extended headers */
140 while (1) {
141 unsigned short extend_size =
142 le16toh(*(unsigned short *)(Buffer + offset - 2));
143
144 if (!extend_size)
145 break;
146
147 *packed_size -= extend_size;
148 offset += extend_size;
149
150 if (BufferSize < offset) {
151 fprintf(stderr,
152 "Error: Buffer to small to contain extended header.\n");
153 return 0;
154 }
155 }
156
157 return offset;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200158}
159
160/*
Luc Verhaegen12c87162009-06-11 14:07:17 +0200161 * CRC Calculation.
Luc Verhaegen462b7762009-06-10 16:56:26 +0200162 */
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400163#define CRCPOLY 0xA001 /* CRC-16 (x^16+x^15+x^2+1) */
164
165unsigned short CRC16Calculate(unsigned char *Buffer, int BufferSize)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200166{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400167 unsigned short CRCTable[0x100];
168 unsigned short crc;
169 int i;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200170
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400171 /* First, initialise our CRCTable */
172 for (i = 0; i < 0x100; i++) {
173 unsigned short r = i;
174 unsigned int j;
Luc Verhaegen12c87162009-06-11 14:07:17 +0200175
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400176 for (j = 0; j < 8; j++) {
177 if (r & 1)
178 r = (r >> 1) ^ CRCPOLY;
179 else
180 r >>= 1;
181 }
182 CRCTable[i] = r;
Luc Verhaegen12c87162009-06-11 14:07:17 +0200183 }
Luc Verhaegen462b7762009-06-10 16:56:26 +0200184
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400185 /* now go over the entire Buffer */
186 crc = 0;
187 for (i = 0; i < BufferSize; i++)
188 crc = CRCTable[(crc ^ Buffer[i]) & 0xFF] ^ (crc >> 8);
Luc Verhaegen462b7762009-06-10 16:56:26 +0200189
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400190 return crc;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200191}
192
193/*
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200194 * Bit handling code.
Luc Verhaegen462b7762009-06-10 16:56:26 +0200195 */
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200196static unsigned char *CompressedBuffer;
197static int CompressedSize;
198static int CompressedOffset;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200199
200static unsigned short bitbuf;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200201static unsigned char subbitbuf, bitcount;
202
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400203static void BitBufInit(unsigned char *Buffer, int BufferSize)
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200204{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400205 CompressedBuffer = Buffer;
206 CompressedOffset = 0;
207 CompressedSize = BufferSize;
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200208
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400209 bitbuf = 0;
210 subbitbuf = 0;
211 bitcount = 0;
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200212}
213
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400214static void fillbuf(unsigned char n)
215{ /* Shift bitbuf n bits left, read n bits */
216 while (n > bitcount) {
217 n -= bitcount;
218 bitbuf = (bitbuf << bitcount) + (subbitbuf >> (8 - bitcount));
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200219
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400220 if (CompressedOffset < CompressedSize) {
221 subbitbuf = CompressedBuffer[CompressedOffset];
222 CompressedOffset++;
223 } else
224 subbitbuf = 0;
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200225
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400226 bitcount = 8;
227 }
228 bitcount -= n;
229 bitbuf = (bitbuf << n) + (subbitbuf >> (8 - n));
230 subbitbuf <<= n;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200231}
232
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400233static unsigned short getbits(unsigned char n)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200234{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400235 unsigned short x;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200236
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400237 x = bitbuf >> (16 - n);
238 fillbuf(n);
Luc Verhaegen462b7762009-06-10 16:56:26 +0200239
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400240 return x;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200241}
242
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400243static unsigned short peekbits(unsigned char n)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200244{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400245 unsigned short x;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200246
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400247 x = bitbuf >> (16 - n);
Luc Verhaegen462b7762009-06-10 16:56:26 +0200248
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400249 return x;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200250}
251
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200252/*
253 *
254 * LHA extraction.
255 *
256 */
257#define MIN(a,b) ((a) <= (b) ? (a) : (b))
258
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400259#define LZHUFF5_DICBIT 13 /* 2^13 = 8KB sliding dictionary */
260#define MAXMATCH 256 /* formerly F (not more than 255 + 1) */
261#define THRESHOLD 3 /* choose optimal value */
262#define NP (LZHUFF5_DICBIT + 1)
263#define NT (16 + 3) /* USHORT + THRESHOLD */
264#define NC (255 + MAXMATCH + 2 - THRESHOLD)
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200265
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400266#define PBIT 4 /* smallest integer such that (1 << PBIT) > * NP */
267#define TBIT 5 /* smallest integer such that (1 << TBIT) > * NT */
268#define CBIT 9 /* smallest integer such that (1 << CBIT) > * NC */
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200269
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400270/* #if NT > NP #define NPT NT #else #define NPT NP #endif */
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200271#define NPT 0x80
272
273static unsigned short left[2 * NC - 1], right[2 * NC - 1];
274
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400275static unsigned short c_table[4096]; /* decode */
276static unsigned short pt_table[256]; /* decode */
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200277
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400278static unsigned char c_len[NC];
279static unsigned char pt_len[NPT];
Luc Verhaegenc8aa2a72009-06-11 04:28:46 +0200280
Anton Kochkovb09d0ef2012-12-21 07:17:56 +0400281static int
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400282make_table(short nchar, unsigned char bitlen[], short tablebits,
283 unsigned short table[])
Luc Verhaegen462b7762009-06-10 16:56:26 +0200284{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400285 unsigned short count[17]; /* count of bitlen */
286 unsigned short weight[17]; /* 0x10000ul >> bitlen */
287 unsigned short start[17]; /* first code of bitlen */
288 unsigned short total;
289 unsigned int i, l;
290 int j, k, m, n, avail;
291 unsigned short *p;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200292
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400293 avail = nchar;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200294
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400295 /* initialize */
296 for (i = 1; i <= 16; i++) {
297 count[i] = 0;
298 weight[i] = 1 << (16 - i);
299 }
Luc Verhaegen462b7762009-06-10 16:56:26 +0200300
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400301 /* count */
302 for (i = 0; i < nchar; i++) {
303 if (bitlen[i] > 16) {
304 /* CVE-2006-4335 */
305 fprintf(stderr, "Error: Bad table (case a)\n");
306 return -1;
307 } else
308 count[bitlen[i]]++;
309 }
Luc Verhaegen462b7762009-06-10 16:56:26 +0200310
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400311 /* calculate first code */
312 total = 0;
313 for (i = 1; i <= 16; i++) {
314 start[i] = total;
315 total += weight[i] * count[i];
316 }
317 if (((total & 0xffff) != 0) || (tablebits > 16)) { /* 16 for weight below */
318 fprintf(stderr, "Error: make_table(): Bad table (case b)\n");
319 return -1;
320 }
Luc Verhaegen462b7762009-06-10 16:56:26 +0200321
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400322 /* shift data for make table. */
323 m = 16 - tablebits;
324 for (i = 1; i <= tablebits; i++) {
325 start[i] >>= m;
326 weight[i] >>= m;
327 }
Luc Verhaegen462b7762009-06-10 16:56:26 +0200328
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400329 /* initialize */
330 j = start[tablebits + 1] >> m;
331 k = MIN(1 << tablebits, 4096);
332 if (j != 0)
333 for (i = j; i < k; i++)
334 table[i] = 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200335
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400336 /* create table and tree */
337 for (j = 0; j < nchar; j++) {
338 k = bitlen[j];
339 if (k == 0)
340 continue;
341 l = start[k] + weight[k];
342 if (k <= tablebits) {
343 /* code in table */
344 l = MIN(l, 4096);
345 for (i = start[k]; i < l; i++)
346 table[i] = j;
347 } else {
348 /* code not in table */
349 i = start[k];
350 if ((i >> m) > 4096) {
351 /* CVE-2006-4337 */
352 fprintf(stderr, "Error: Bad table (case c)");
353 exit(1);
354 }
355 p = &table[i >> m];
356 i <<= tablebits;
357 n = k - tablebits;
358 /* make tree (n length) */
359 while (--n >= 0) {
360 if (*p == 0) {
361 right[avail] = left[avail] = 0;
362 *p = avail++;
363 }
364 if (i & 0x8000)
365 p = &right[*p];
366 else
367 p = &left[*p];
368 i <<= 1;
369 }
370 *p = j;
371 }
372 start[k] = l;
373 }
374 return 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200375}
376
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400377static int read_pt_len(short nn, short nbit, short i_special)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200378{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400379 int i, c, n;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200380
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400381 n = getbits(nbit);
382 if (n == 0) {
383 c = getbits(nbit);
384 for (i = 0; i < nn; i++)
385 pt_len[i] = 0;
386 for (i = 0; i < 256; i++)
387 pt_table[i] = c;
388 } else {
389 i = 0;
390 while (i < MIN(n, NPT)) {
391 c = peekbits(3);
392 if (c != 7)
393 fillbuf(3);
394 else {
395 unsigned short mask = 1 << (16 - 4);
396 while (mask & bitbuf) {
397 mask >>= 1;
398 c++;
399 }
400 fillbuf(c - 3);
401 }
Luc Verhaegen462b7762009-06-10 16:56:26 +0200402
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400403 pt_len[i++] = c;
404 if (i == i_special) {
405 c = getbits(2);
406 while (--c >= 0 && i < NPT)
407 pt_len[i++] = 0;
408 }
409 }
410 while (i < nn)
411 pt_len[i++] = 0;
412
413 if (make_table(nn, pt_len, 8, pt_table) == -1)
414 return -1;
415 }
416 return 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200417}
418
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400419static int read_c_len(void)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200420{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400421 short i, c, n;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200422
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400423 n = getbits(CBIT);
424 if (n == 0) {
425 c = getbits(CBIT);
426 for (i = 0; i < NC; i++)
427 c_len[i] = 0;
428 for (i = 0; i < 4096; i++)
429 c_table[i] = c;
430 } else {
431 i = 0;
432 while (i < MIN(n, NC)) {
433 c = pt_table[peekbits(8)];
434 if (c >= NT) {
435 unsigned short mask = 1 << (16 - 9);
436 do {
437 if (bitbuf & mask)
438 c = right[c];
439 else
440 c = left[c];
441 mask >>= 1;
442 } while (c >= NT && (mask || c != left[c])); /* CVE-2006-4338 */
443 }
444 fillbuf(pt_len[c]);
445 if (c <= 2) {
446 if (c == 0)
447 c = 1;
448 else if (c == 1)
449 c = getbits(4) + 3;
450 else
451 c = getbits(CBIT) + 20;
452 while (--c >= 0)
453 c_len[i++] = 0;
454 } else
455 c_len[i++] = c - 2;
456 }
457 while (i < NC)
458 c_len[i++] = 0;
459
460 if (make_table(NC, c_len, 12, c_table) == -1)
461 return -1;
462 }
463 return 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200464}
465
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400466static unsigned short decode_c_st1(void)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200467{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400468 unsigned short j, mask;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200469
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400470 j = c_table[peekbits(12)];
471 if (j < NC)
472 fillbuf(c_len[j]);
473 else {
474 fillbuf(12);
475 mask = 1 << (16 - 1);
476 do {
477 if (bitbuf & mask)
478 j = right[j];
479 else
480 j = left[j];
481 mask >>= 1;
482 } while (j >= NC && (mask || j != left[j])); /* CVE-2006-4338 */
483 fillbuf(c_len[j] - 12);
484 }
485 return j;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200486}
487
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400488static unsigned short decode_p_st1(void)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200489{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400490 unsigned short j, mask;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200491
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400492 j = pt_table[peekbits(8)];
493 if (j < NP)
494 fillbuf(pt_len[j]);
495 else {
496 fillbuf(8);
497 mask = 1 << (16 - 1);
498 do {
499 if (bitbuf & mask)
500 j = right[j];
501 else
502 j = left[j];
503 mask >>= 1;
504 } while (j >= NP && (mask || j != left[j])); /* CVE-2006-4338 */
505 fillbuf(pt_len[j] - 8);
506 }
507 if (j != 0)
508 j = (1 << (j - 1)) + getbits(j - 1);
509 return j;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200510}
511
Anton Kochkovb09d0ef2012-12-21 07:17:56 +0400512int
Luc Verhaegen9af97842009-06-11 14:28:33 +0200513LH5Decode(unsigned char *PackedBuffer, int PackedBufferSize,
Luc Verhaegenb8941802009-06-15 20:31:11 +0200514 unsigned char *OutputBuffer, int OutputBufferSize)
Luc Verhaegen462b7762009-06-10 16:56:26 +0200515{
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400516 unsigned short blocksize = 0;
517 unsigned int i, c;
518 int n = 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200519
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400520 BitBufInit(PackedBuffer, PackedBufferSize);
521 fillbuf(2 * 8);
Luc Verhaegen462b7762009-06-10 16:56:26 +0200522
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400523 while (n < OutputBufferSize) {
524 if (blocksize == 0) {
525 blocksize = getbits(16);
526
527 if (read_pt_len(NT, TBIT, 3) == -1)
528 return -1;
529 if (read_c_len() == -1)
530 return -1;
531 if (read_pt_len(NP, PBIT, -1) == -1)
532 return -1;
533 }
534 blocksize--;
535 c = decode_c_st1();
536
537 if (c < 256)
538 OutputBuffer[n++] = c;
539 else {
540 int length = c - 256 + THRESHOLD;
541 int offset = 1 + decode_p_st1();
542
Uwe Kleine-K├Âniga2576432015-06-11 22:38:56 +0200543 if (offset > n)
544 return -1;
545
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400546 for (i = 0; i < length; i++) {
547 OutputBuffer[n] = OutputBuffer[n - offset];
548 n++;
549 }
550 }
Luc Verhaegen462b7762009-06-10 16:56:26 +0200551 }
Anton Kochkov8f9427f2013-04-07 13:20:30 +0400552 return 0;
Luc Verhaegen462b7762009-06-10 16:56:26 +0200553}