diff options
| author | Mark Adler <madler@alumni.caltech.edu> | 2012-08-18 17:59:50 -0700 |
|---|---|---|
| committer | Mark Adler <madler@alumni.caltech.edu> | 2012-08-18 18:07:26 -0700 |
| commit | 17068938ce5544ec3728402abd39bf3c55aec113 (patch) | |
| tree | e366e8de99ddad7b53231d27bb797bd608ccbfce | |
| parent | 3d9df6ecf83a41a3990fbff5c276f854d158e8ad (diff) | |
| download | zlib-17068938ce5544ec3728402abd39bf3c55aec113.tar.gz zlib-17068938ce5544ec3728402abd39bf3c55aec113.tar.bz2 zlib-17068938ce5544ec3728402abd39bf3c55aec113.zip | |
Avoid shift equal to bits in type (caused endless loop).
Also clean up comparisons between different types, and some odd
indentation problems that showed up somehow.
A new endless loop was introduced by the clang compiler, which
apparently does odd things when the right operand of << is equal to
or greater than the number of bits in the type. The C standard in
fact states that the behavior of << is undefined in that case. The
loop was rewritten to use single-bit shifts.
| -rw-r--r-- | examples/enough.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/examples/enough.c b/examples/enough.c index c40410b..b991144 100644 --- a/examples/enough.c +++ b/examples/enough.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* enough.c -- determine the maximum size of inflate's Huffman code tables over | 1 | /* enough.c -- determine the maximum size of inflate's Huffman code tables over |
| 2 | * all possible valid and complete Huffman codes, subject to a length limit. | 2 | * all possible valid and complete Huffman codes, subject to a length limit. |
| 3 | * Copyright (C) 2007, 2008 Mark Adler | 3 | * Copyright (C) 2007, 2008, 2012 Mark Adler |
| 4 | * Version 1.3 17 February 2008 Mark Adler | 4 | * Version 1.4 18 August 2012 Mark Adler |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | /* Version history: | 7 | /* Version history: |
| @@ -14,6 +14,9 @@ | |||
| 14 | 1.3 17 Feb 2008 Add argument for initial root table size | 14 | 1.3 17 Feb 2008 Add argument for initial root table size |
| 15 | Fix bug for initial root table size == max - 1 | 15 | Fix bug for initial root table size == max - 1 |
| 16 | Use a macro to compute the history index | 16 | Use a macro to compute the history index |
| 17 | 1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!) | ||
| 18 | Clean up comparisons of different types | ||
| 19 | Clean up code indentation | ||
| 17 | */ | 20 | */ |
| 18 | 21 | ||
| 19 | /* | 22 | /* |
| @@ -236,8 +239,8 @@ local big_t count(int syms, int len, int left) | |||
| 236 | for (use = least; use <= most; use++) { | 239 | for (use = least; use <= most; use++) { |
| 237 | got = count(syms - use, len + 1, (left - use) << 1); | 240 | got = count(syms - use, len + 1, (left - use) << 1); |
| 238 | sum += got; | 241 | sum += got; |
| 239 | if (got == -1 || sum < got) /* overflow */ | 242 | if (got == (big_t)0 - 1 || sum < got) /* overflow */ |
| 240 | return -1; | 243 | return (big_t)0 - 1; |
| 241 | } | 244 | } |
| 242 | 245 | ||
| 243 | /* verify that all recursive calls are productive */ | 246 | /* verify that all recursive calls are productive */ |
| @@ -458,6 +461,7 @@ int main(int argc, char **argv) | |||
| 458 | int n; /* number of symbols to code for this run */ | 461 | int n; /* number of symbols to code for this run */ |
| 459 | big_t got; /* return value of count() */ | 462 | big_t got; /* return value of count() */ |
| 460 | big_t sum; /* accumulated number of codes over n */ | 463 | big_t sum; /* accumulated number of codes over n */ |
| 464 | code_t word; /* for counting bits in code_t */ | ||
| 461 | 465 | ||
| 462 | /* set up globals for cleanup() */ | 466 | /* set up globals for cleanup() */ |
| 463 | code = NULL; | 467 | code = NULL; |
| @@ -466,19 +470,19 @@ int main(int argc, char **argv) | |||
| 466 | 470 | ||
| 467 | /* get arguments -- default to the deflate literal/length code */ | 471 | /* get arguments -- default to the deflate literal/length code */ |
| 468 | syms = 286; | 472 | syms = 286; |
| 469 | root = 9; | 473 | root = 9; |
| 470 | max = 15; | 474 | max = 15; |
| 471 | if (argc > 1) { | 475 | if (argc > 1) { |
| 472 | syms = atoi(argv[1]); | 476 | syms = atoi(argv[1]); |
| 473 | if (argc > 2) { | 477 | if (argc > 2) { |
| 474 | root = atoi(argv[2]); | 478 | root = atoi(argv[2]); |
| 475 | if (argc > 3) | 479 | if (argc > 3) |
| 476 | max = atoi(argv[3]); | 480 | max = atoi(argv[3]); |
| 477 | } | 481 | } |
| 478 | } | 482 | } |
| 479 | if (argc > 4 || syms < 2 || root < 1 || max < 1) { | 483 | if (argc > 4 || syms < 2 || root < 1 || max < 1) { |
| 480 | fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n", | 484 | fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n", |
| 481 | stderr); | 485 | stderr); |
| 482 | return 1; | 486 | return 1; |
| 483 | } | 487 | } |
| 484 | 488 | ||
| @@ -487,18 +491,17 @@ int main(int argc, char **argv) | |||
| 487 | max = syms - 1; | 491 | max = syms - 1; |
| 488 | 492 | ||
| 489 | /* determine the number of bits in a code_t */ | 493 | /* determine the number of bits in a code_t */ |
| 490 | n = 0; | 494 | for (n = 0, word = 1; word; n++, word <<= 1) |
| 491 | while (((code_t)1 << n) != 0) | 495 | ; |
| 492 | n++; | ||
| 493 | 496 | ||
| 494 | /* make sure that the calculation of most will not overflow */ | 497 | /* make sure that the calculation of most will not overflow */ |
| 495 | if (max > n || syms - 2 >= (((code_t)0 - 1) >> (max - 1))) { | 498 | if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) { |
| 496 | fputs("abort: code length too long for internal types\n", stderr); | 499 | fputs("abort: code length too long for internal types\n", stderr); |
| 497 | return 1; | 500 | return 1; |
| 498 | } | 501 | } |
| 499 | 502 | ||
| 500 | /* reject impossible code requests */ | 503 | /* reject impossible code requests */ |
| 501 | if (syms - 1 > ((code_t)1 << max) - 1) { | 504 | if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) { |
| 502 | fprintf(stderr, "%d symbols cannot be coded in %d bits\n", | 505 | fprintf(stderr, "%d symbols cannot be coded in %d bits\n", |
| 503 | syms, max); | 506 | syms, max); |
| 504 | return 1; | 507 | return 1; |
| @@ -532,7 +535,7 @@ int main(int argc, char **argv) | |||
| 532 | for (n = 2; n <= syms; n++) { | 535 | for (n = 2; n <= syms; n++) { |
| 533 | got = count(n, 1, 2); | 536 | got = count(n, 1, 2); |
| 534 | sum += got; | 537 | sum += got; |
| 535 | if (got == -1 || sum < got) { /* overflow */ | 538 | if (got == (big_t)0 - 1 || sum < got) { /* overflow */ |
| 536 | fputs("abort: can't count that high!\n", stderr); | 539 | fputs("abort: can't count that high!\n", stderr); |
| 537 | cleanup(); | 540 | cleanup(); |
| 538 | return 1; | 541 | return 1; |
| @@ -556,9 +559,9 @@ int main(int argc, char **argv) | |||
| 556 | } | 559 | } |
| 557 | 560 | ||
| 558 | /* find and show maximum inflate table usage */ | 561 | /* find and show maximum inflate table usage */ |
| 559 | if (root > max) /* reduce root to max length */ | 562 | if (root > max) /* reduce root to max length */ |
| 560 | root = max; | 563 | root = max; |
| 561 | if (syms < ((code_t)1 << (root + 1))) | 564 | if ((code_t)syms < ((code_t)1 << (root + 1))) |
| 562 | enough(syms); | 565 | enough(syms); |
| 563 | else | 566 | else |
| 564 | puts("cannot handle minimum code lengths > root"); | 567 | puts("cannot handle minimum code lengths > root"); |
