| Summary: | gzip compression level and off-by-one bug | ||
|---|---|---|---|
| Product: | Busybox | Reporter: | Natanael Copa <ncopa> |
| Component: | Other | Assignee: | unassigned |
| Status: | RESOLVED FIXED | ||
| Severity: | major | CC: | busybox-cvs |
| Priority: | P5 | ||
| Version: | 1.24.x | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Host: | Target: | ||
| Build: | |||
Fixed in git. |
gzip -9 will output a file that is bigger than when using -1. This appear to be due to the logic in mapping the option to index for gzip_level_config[] being broken, which results in an off-by-one error. To analyze what is actually going on, try this temp patch: diff --git a/archival/gzip.c b/archival/gzip.c index 8f1e4ff..272d49a 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -2224,6 +2224,7 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) if (opt & 0x7) opt |= 1 << 4; opt = ffs(opt >> 3); + fprintf(stderr, "opt=%x\n", opt); max_chain_length = 1 << gzip_level_config[opt].chain_shift; good_match = gzip_level_config[opt].good; max_lazy_match = gzip_level_config[opt].lazy2 * 2; and run: for i in $(seq 1 9); do echo -n "-$i: " ; ./busybox gzip -c -$i /bin/busybox > /dev/null; done The output gives: -1: opt=2 -2: opt=2 -3: opt=2 -4: opt=1 -5: opt=2 -6: opt=3 -7: opt=4 -8: opt=5 -9: opt=6 Also note the output of: ./busybox gzip -c ./busybox >/dev/null opt=4 This means that effectively: - gzip without options will currently default to compression level 8 instead of level 6 as the comments claims. - gzip -1|-2|-3 will currently set compression level to level 6. - gzip -4|-5|-6|-7|-8 will currently set compression level 5-9 - gzip -9 (with opt=6) will result in out-of-bounds access of gzip_level_config[] array