diff options
Diffstat (limited to 'decompress.c')
-rw-r--r-- | decompress.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/decompress.c b/decompress.c index 31f8b67..cdced18 100644 --- a/decompress.c +++ b/decompress.c | |||
@@ -8,7 +8,7 @@ | |||
8 | This file is a part of bzip2 and/or libbzip2, a program and | 8 | This file is a part of bzip2 and/or libbzip2, a program and |
9 | library for lossless, block-sorting data compression. | 9 | library for lossless, block-sorting data compression. |
10 | 10 | ||
11 | Copyright (C) 1996-1999 Julian R Seward. All rights reserved. | 11 | Copyright (C) 1996-2000 Julian R Seward. All rights reserved. |
12 | 12 | ||
13 | Redistribution and use in source and binary forms, with or without | 13 | Redistribution and use in source and binary forms, with or without |
14 | modification, are permitted provided that the following conditions | 14 | modification, are permitted provided that the following conditions |
@@ -43,7 +43,7 @@ | |||
43 | 43 | ||
44 | Julian Seward, Cambridge, UK. | 44 | Julian Seward, Cambridge, UK. |
45 | jseward@acm.org | 45 | jseward@acm.org |
46 | bzip2/libbzip2 version 0.9.5 of 24 May 1999 | 46 | bzip2/libbzip2 version 1.0 of 21 March 2000 |
47 | 47 | ||
48 | This program is based on (at least) the work of: | 48 | This program is based on (at least) the work of: |
49 | Mike Burrows | 49 | Mike Burrows |
@@ -99,7 +99,9 @@ void makeMaps_d ( DState* s ) | |||
99 | s->bsLive += 8; \ | 99 | s->bsLive += 8; \ |
100 | s->strm->next_in++; \ | 100 | s->strm->next_in++; \ |
101 | s->strm->avail_in--; \ | 101 | s->strm->avail_in--; \ |
102 | s->strm->total_in++; \ | 102 | s->strm->total_in_lo32++; \ |
103 | if (s->strm->total_in_lo32 == 0) \ | ||
104 | s->strm->total_in_hi32++; \ | ||
103 | } | 105 | } |
104 | 106 | ||
105 | #define GET_UCHAR(lll,uuu) \ | 107 | #define GET_UCHAR(lll,uuu) \ |
@@ -113,6 +115,8 @@ void makeMaps_d ( DState* s ) | |||
113 | { \ | 115 | { \ |
114 | if (groupPos == 0) { \ | 116 | if (groupPos == 0) { \ |
115 | groupNo++; \ | 117 | groupNo++; \ |
118 | if (groupNo >= nSelectors) \ | ||
119 | RETURN(BZ_DATA_ERROR); \ | ||
116 | groupPos = BZ_G_SIZE; \ | 120 | groupPos = BZ_G_SIZE; \ |
117 | gSel = s->selector[groupNo]; \ | 121 | gSel = s->selector[groupNo]; \ |
118 | gMinlen = s->minLens[gSel]; \ | 122 | gMinlen = s->minLens[gSel]; \ |
@@ -123,17 +127,23 @@ void makeMaps_d ( DState* s ) | |||
123 | groupPos--; \ | 127 | groupPos--; \ |
124 | zn = gMinlen; \ | 128 | zn = gMinlen; \ |
125 | GET_BITS(label1, zvec, zn); \ | 129 | GET_BITS(label1, zvec, zn); \ |
126 | while (zvec > gLimit[zn]) { \ | 130 | while (1) { \ |
131 | if (zn > 20 /* the longest code */) \ | ||
132 | RETURN(BZ_DATA_ERROR); \ | ||
133 | if (zvec <= gLimit[zn]) break; \ | ||
127 | zn++; \ | 134 | zn++; \ |
128 | GET_BIT(label2, zj); \ | 135 | GET_BIT(label2, zj); \ |
129 | zvec = (zvec << 1) | zj; \ | 136 | zvec = (zvec << 1) | zj; \ |
130 | }; \ | 137 | }; \ |
138 | if (zvec - gBase[zn] < 0 \ | ||
139 | || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ | ||
140 | RETURN(BZ_DATA_ERROR); \ | ||
131 | lval = gPerm[zvec - gBase[zn]]; \ | 141 | lval = gPerm[zvec - gBase[zn]]; \ |
132 | } | 142 | } |
133 | 143 | ||
134 | 144 | ||
135 | /*---------------------------------------------------*/ | 145 | /*---------------------------------------------------*/ |
136 | Int32 decompress ( DState* s ) | 146 | Int32 BZ2_decompress ( DState* s ) |
137 | { | 147 | { |
138 | UChar uc; | 148 | UChar uc; |
139 | Int32 retVal; | 149 | Int32 retVal; |
@@ -288,6 +298,11 @@ Int32 decompress ( DState* s ) | |||
288 | GET_UCHAR(BZ_X_ORIGPTR_3, uc); | 298 | GET_UCHAR(BZ_X_ORIGPTR_3, uc); |
289 | s->origPtr = (s->origPtr << 8) | ((Int32)uc); | 299 | s->origPtr = (s->origPtr << 8) | ((Int32)uc); |
290 | 300 | ||
301 | if (s->origPtr < 0) | ||
302 | RETURN(BZ_DATA_ERROR); | ||
303 | if (s->origPtr > 10 + 100000*s->blockSize100k) | ||
304 | RETURN(BZ_DATA_ERROR); | ||
305 | |||
291 | /*--- Receive the mapping table ---*/ | 306 | /*--- Receive the mapping table ---*/ |
292 | for (i = 0; i < 16; i++) { | 307 | for (i = 0; i < 16; i++) { |
293 | GET_BIT(BZ_X_MAPPING_1, uc); | 308 | GET_BIT(BZ_X_MAPPING_1, uc); |
@@ -305,18 +320,21 @@ Int32 decompress ( DState* s ) | |||
305 | if (uc == 1) s->inUse[i * 16 + j] = True; | 320 | if (uc == 1) s->inUse[i * 16 + j] = True; |
306 | } | 321 | } |
307 | makeMaps_d ( s ); | 322 | makeMaps_d ( s ); |
323 | if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); | ||
308 | alphaSize = s->nInUse+2; | 324 | alphaSize = s->nInUse+2; |
309 | 325 | ||
310 | /*--- Now the selectors ---*/ | 326 | /*--- Now the selectors ---*/ |
311 | GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); | 327 | GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); |
328 | if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); | ||
312 | GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); | 329 | GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); |
330 | if (nSelectors < 1) RETURN(BZ_DATA_ERROR); | ||
313 | for (i = 0; i < nSelectors; i++) { | 331 | for (i = 0; i < nSelectors; i++) { |
314 | j = 0; | 332 | j = 0; |
315 | while (True) { | 333 | while (True) { |
316 | GET_BIT(BZ_X_SELECTOR_3, uc); | 334 | GET_BIT(BZ_X_SELECTOR_3, uc); |
317 | if (uc == 0) break; | 335 | if (uc == 0) break; |
318 | j++; | 336 | j++; |
319 | if (j > 5) RETURN(BZ_DATA_ERROR); | 337 | if (j >= nGroups) RETURN(BZ_DATA_ERROR); |
320 | } | 338 | } |
321 | s->selectorMtf[i] = j; | 339 | s->selectorMtf[i] = j; |
322 | } | 340 | } |
@@ -358,7 +376,7 @@ Int32 decompress ( DState* s ) | |||
358 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; | 376 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; |
359 | if (s->len[t][i] < minLen) minLen = s->len[t][i]; | 377 | if (s->len[t][i] < minLen) minLen = s->len[t][i]; |
360 | } | 378 | } |
361 | hbCreateDecodeTables ( | 379 | BZ2_hbCreateDecodeTables ( |
362 | &(s->limit[t][0]), | 380 | &(s->limit[t][0]), |
363 | &(s->base[t][0]), | 381 | &(s->base[t][0]), |
364 | &(s->perm[t][0]), | 382 | &(s->perm[t][0]), |
@@ -392,7 +410,6 @@ Int32 decompress ( DState* s ) | |||
392 | /*-- end MTF init --*/ | 410 | /*-- end MTF init --*/ |
393 | 411 | ||
394 | nblock = 0; | 412 | nblock = 0; |
395 | |||
396 | GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); | 413 | GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); |
397 | 414 | ||
398 | while (True) { | 415 | while (True) { |
@@ -417,23 +434,24 @@ Int32 decompress ( DState* s ) | |||
417 | 434 | ||
418 | if (s->smallDecompress) | 435 | if (s->smallDecompress) |
419 | while (es > 0) { | 436 | while (es > 0) { |
437 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); | ||
420 | s->ll16[nblock] = (UInt16)uc; | 438 | s->ll16[nblock] = (UInt16)uc; |
421 | nblock++; | 439 | nblock++; |
422 | es--; | 440 | es--; |
423 | } | 441 | } |
424 | else | 442 | else |
425 | while (es > 0) { | 443 | while (es > 0) { |
444 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); | ||
426 | s->tt[nblock] = (UInt32)uc; | 445 | s->tt[nblock] = (UInt32)uc; |
427 | nblock++; | 446 | nblock++; |
428 | es--; | 447 | es--; |
429 | }; | 448 | }; |
430 | 449 | ||
431 | if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR); | ||
432 | continue; | 450 | continue; |
433 | 451 | ||
434 | } else { | 452 | } else { |
435 | 453 | ||
436 | if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR); | 454 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); |
437 | 455 | ||
438 | /*-- uc = MTF ( nextSym-1 ) --*/ | 456 | /*-- uc = MTF ( nextSym-1 ) --*/ |
439 | { | 457 | { |
@@ -500,6 +518,12 @@ Int32 decompress ( DState* s ) | |||
500 | } | 518 | } |
501 | } | 519 | } |
502 | 520 | ||
521 | /* Now we know what nblock is, we can do a better sanity | ||
522 | check on s->origPtr. | ||
523 | */ | ||
524 | if (s->origPtr < 0 || s->origPtr >= nblock) | ||
525 | RETURN(BZ_DATA_ERROR); | ||
526 | |||
503 | s->state_out_len = 0; | 527 | s->state_out_len = 0; |
504 | s->state_out_ch = 0; | 528 | s->state_out_ch = 0; |
505 | BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); | 529 | BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); |