diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2016-10-24 20:11:41 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2016-10-24 21:07:43 -0700 |
commit | b516b4bdd7c0c9f0858adfebf732089014f7b282 (patch) | |
tree | fcee291aca78e7bf475e0060e42f18a40174c947 /deflate.c | |
parent | 77fd7e56bfc75b4194145060bb1ec5256ce077c6 (diff) | |
download | zlib-b516b4bdd7c0c9f0858adfebf732089014f7b282.tar.gz zlib-b516b4bdd7c0c9f0858adfebf732089014f7b282.tar.bz2 zlib-b516b4bdd7c0c9f0858adfebf732089014f7b282.zip |
Do a more thorough check of the state for every stream call.
This verifies that the state has been initialized, that it is the
expected type of state, deflate or inflate, and that at least the
first several bytes of the internal state have not been clobbered.
Diffstat (limited to 'deflate.c')
-rw-r--r-- | deflate.c | 59 |
1 files changed, 36 insertions, 23 deletions
@@ -73,6 +73,7 @@ typedef enum { | |||
73 | typedef block_state (*compress_func) OF((deflate_state *s, int flush)); | 73 | typedef block_state (*compress_func) OF((deflate_state *s, int flush)); |
74 | /* Compression function. Returns the block state after the call. */ | 74 | /* Compression function. Returns the block state after the call. */ |
75 | 75 | ||
76 | local int deflateStateCheck OF((z_streamp strm)); | ||
76 | local void fill_window OF((deflate_state *s)); | 77 | local void fill_window OF((deflate_state *s)); |
77 | local block_state deflate_stored OF((deflate_state *s, int flush)); | 78 | local block_state deflate_stored OF((deflate_state *s, int flush)); |
78 | local block_state deflate_fast OF((deflate_state *s, int flush)); | 79 | local block_state deflate_fast OF((deflate_state *s, int flush)); |
@@ -271,6 +272,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
271 | if (s == Z_NULL) return Z_MEM_ERROR; | 272 | if (s == Z_NULL) return Z_MEM_ERROR; |
272 | strm->state = (struct internal_state FAR *)s; | 273 | strm->state = (struct internal_state FAR *)s; |
273 | s->strm = strm; | 274 | s->strm = strm; |
275 | s->status = INIT_STATE; /* to pass state test in deflateReset() */ | ||
274 | 276 | ||
275 | s->wrap = wrap; | 277 | s->wrap = wrap; |
276 | s->gzhead = Z_NULL; | 278 | s->gzhead = Z_NULL; |
@@ -312,6 +314,28 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
312 | return deflateReset(strm); | 314 | return deflateReset(strm); |
313 | } | 315 | } |
314 | 316 | ||
317 | /* ========================================================================= | ||
318 | * Check for a valid deflate stream state. Return 0 if ok, 1 if not. | ||
319 | */ | ||
320 | local int deflateStateCheck (strm) | ||
321 | z_streamp strm; | ||
322 | { | ||
323 | deflate_state *s; | ||
324 | if (strm == Z_NULL || | ||
325 | strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) | ||
326 | return 1; | ||
327 | s = strm->state; | ||
328 | if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && | ||
329 | s->status != EXTRA_STATE && | ||
330 | s->status != NAME_STATE && | ||
331 | s->status != COMMENT_STATE && | ||
332 | s->status != HCRC_STATE && | ||
333 | s->status != BUSY_STATE && | ||
334 | s->status != FINISH_STATE)) | ||
335 | return 1; | ||
336 | return 0; | ||
337 | } | ||
338 | |||
315 | /* ========================================================================= */ | 339 | /* ========================================================================= */ |
316 | int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) | 340 | int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) |
317 | z_streamp strm; | 341 | z_streamp strm; |
@@ -324,7 +348,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) | |||
324 | unsigned avail; | 348 | unsigned avail; |
325 | z_const unsigned char *next; | 349 | z_const unsigned char *next; |
326 | 350 | ||
327 | if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) | 351 | if (deflateStateCheck(strm) || dictionary == Z_NULL) |
328 | return Z_STREAM_ERROR; | 352 | return Z_STREAM_ERROR; |
329 | s = strm->state; | 353 | s = strm->state; |
330 | wrap = s->wrap; | 354 | wrap = s->wrap; |
@@ -387,8 +411,7 @@ int ZEXPORT deflateResetKeep (strm) | |||
387 | { | 411 | { |
388 | deflate_state *s; | 412 | deflate_state *s; |
389 | 413 | ||
390 | if (strm == Z_NULL || strm->state == Z_NULL || | 414 | if (deflateStateCheck(strm)) { |
391 | strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { | ||
392 | return Z_STREAM_ERROR; | 415 | return Z_STREAM_ERROR; |
393 | } | 416 | } |
394 | 417 | ||
@@ -433,8 +456,8 @@ int ZEXPORT deflateSetHeader (strm, head) | |||
433 | z_streamp strm; | 456 | z_streamp strm; |
434 | gz_headerp head; | 457 | gz_headerp head; |
435 | { | 458 | { |
436 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 459 | if (deflateStateCheck(strm) || strm->state->wrap != 2) |
437 | if (strm->state->wrap != 2) return Z_STREAM_ERROR; | 460 | return Z_STREAM_ERROR; |
438 | strm->state->gzhead = head; | 461 | strm->state->gzhead = head; |
439 | return Z_OK; | 462 | return Z_OK; |
440 | } | 463 | } |
@@ -445,7 +468,7 @@ int ZEXPORT deflatePending (strm, pending, bits) | |||
445 | int *bits; | 468 | int *bits; |
446 | z_streamp strm; | 469 | z_streamp strm; |
447 | { | 470 | { |
448 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 471 | if (deflateStateCheck(strm)) return Z_STREAM_ERROR; |
449 | if (pending != Z_NULL) | 472 | if (pending != Z_NULL) |
450 | *pending = strm->state->pending; | 473 | *pending = strm->state->pending; |
451 | if (bits != Z_NULL) | 474 | if (bits != Z_NULL) |
@@ -462,7 +485,7 @@ int ZEXPORT deflatePrime (strm, bits, value) | |||
462 | deflate_state *s; | 485 | deflate_state *s; |
463 | int put; | 486 | int put; |
464 | 487 | ||
465 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 488 | if (deflateStateCheck(strm)) return Z_STREAM_ERROR; |
466 | s = strm->state; | 489 | s = strm->state; |
467 | if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) | 490 | if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) |
468 | return Z_BUF_ERROR; | 491 | return Z_BUF_ERROR; |
@@ -489,7 +512,7 @@ int ZEXPORT deflateParams(strm, level, strategy) | |||
489 | compress_func func; | 512 | compress_func func; |
490 | int err = Z_OK; | 513 | int err = Z_OK; |
491 | 514 | ||
492 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 515 | if (deflateStateCheck(strm)) return Z_STREAM_ERROR; |
493 | s = strm->state; | 516 | s = strm->state; |
494 | 517 | ||
495 | #ifdef FASTEST | 518 | #ifdef FASTEST |
@@ -529,7 +552,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) | |||
529 | { | 552 | { |
530 | deflate_state *s; | 553 | deflate_state *s; |
531 | 554 | ||
532 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 555 | if (deflateStateCheck(strm)) return Z_STREAM_ERROR; |
533 | s = strm->state; | 556 | s = strm->state; |
534 | s->good_match = (uInt)good_length; | 557 | s->good_match = (uInt)good_length; |
535 | s->max_lazy_match = (uInt)max_lazy; | 558 | s->max_lazy_match = (uInt)max_lazy; |
@@ -568,7 +591,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) | |||
568 | ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; | 591 | ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; |
569 | 592 | ||
570 | /* if can't get parameters, return conservative bound plus zlib wrapper */ | 593 | /* if can't get parameters, return conservative bound plus zlib wrapper */ |
571 | if (strm == Z_NULL || strm->state == Z_NULL) | 594 | if (deflateStateCheck(strm)) |
572 | return complen + 6; | 595 | return complen + 6; |
573 | 596 | ||
574 | /* compute wrapper length */ | 597 | /* compute wrapper length */ |
@@ -661,8 +684,7 @@ int ZEXPORT deflate (strm, flush) | |||
661 | int old_flush; /* value of flush param for previous deflate call */ | 684 | int old_flush; /* value of flush param for previous deflate call */ |
662 | deflate_state *s; | 685 | deflate_state *s; |
663 | 686 | ||
664 | if (strm == Z_NULL || strm->state == Z_NULL || | 687 | if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { |
665 | flush > Z_BLOCK || flush < 0) { | ||
666 | return Z_STREAM_ERROR; | 688 | return Z_STREAM_ERROR; |
667 | } | 689 | } |
668 | s = strm->state; | 690 | s = strm->state; |
@@ -973,18 +995,9 @@ int ZEXPORT deflateEnd (strm) | |||
973 | { | 995 | { |
974 | int status; | 996 | int status; |
975 | 997 | ||
976 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 998 | if (deflateStateCheck(strm)) return Z_STREAM_ERROR; |
977 | 999 | ||
978 | status = strm->state->status; | 1000 | status = strm->state->status; |
979 | if (status != INIT_STATE && | ||
980 | status != EXTRA_STATE && | ||
981 | status != NAME_STATE && | ||
982 | status != COMMENT_STATE && | ||
983 | status != HCRC_STATE && | ||
984 | status != BUSY_STATE && | ||
985 | status != FINISH_STATE) { | ||
986 | return Z_STREAM_ERROR; | ||
987 | } | ||
988 | 1001 | ||
989 | /* Deallocate in reverse order of allocations: */ | 1002 | /* Deallocate in reverse order of allocations: */ |
990 | TRY_FREE(strm, strm->state->pending_buf); | 1003 | TRY_FREE(strm, strm->state->pending_buf); |
@@ -1015,7 +1028,7 @@ int ZEXPORT deflateCopy (dest, source) | |||
1015 | ushf *overlay; | 1028 | ushf *overlay; |
1016 | 1029 | ||
1017 | 1030 | ||
1018 | if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { | 1031 | if (deflateStateCheck(source) || dest == Z_NULL) { |
1019 | return Z_STREAM_ERROR; | 1032 | return Z_STREAM_ERROR; |
1020 | } | 1033 | } |
1021 | 1034 | ||