cannam@89: cannam@89: /* A test program written to test robustness to decompression of cannam@89: corrupted data. Usage is cannam@89: unzcrash filename cannam@89: and the program will read the specified file, compress it (in memory), cannam@89: and then repeatedly decompress it, each time with a different bit of cannam@89: the compressed data inverted, so as to test all possible one-bit errors. cannam@89: This should not cause any invalid memory accesses. If it does, cannam@89: I want to know about it! cannam@89: cannam@89: PS. As you can see from the above description, the process is cannam@89: incredibly slow. A file of size eg 5KB will cause it to run for cannam@89: many hours. cannam@89: */ cannam@89: cannam@89: /* ------------------------------------------------------------------ cannam@89: This file is part of bzip2/libbzip2, a program and library for cannam@89: lossless, block-sorting data compression. cannam@89: cannam@89: bzip2/libbzip2 version 1.0.6 of 6 September 2010 cannam@89: Copyright (C) 1996-2010 Julian Seward cannam@89: cannam@89: Please read the WARNING, DISCLAIMER and PATENTS sections in the cannam@89: README file. cannam@89: cannam@89: This program is released under the terms of the license contained cannam@89: in the file LICENSE. cannam@89: ------------------------------------------------------------------ */ cannam@89: cannam@89: cannam@89: #include cannam@89: #include cannam@89: #include "bzlib.h" cannam@89: cannam@89: #define M_BLOCK 1000000 cannam@89: cannam@89: typedef unsigned char uchar; cannam@89: cannam@89: #define M_BLOCK_OUT (M_BLOCK + 1000000) cannam@89: uchar inbuf[M_BLOCK]; cannam@89: uchar outbuf[M_BLOCK_OUT]; cannam@89: uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)]; cannam@89: cannam@89: int nIn, nOut, nZ; cannam@89: cannam@89: static char *bzerrorstrings[] = { cannam@89: "OK" cannam@89: ,"SEQUENCE_ERROR" cannam@89: ,"PARAM_ERROR" cannam@89: ,"MEM_ERROR" cannam@89: ,"DATA_ERROR" cannam@89: ,"DATA_ERROR_MAGIC" cannam@89: ,"IO_ERROR" cannam@89: ,"UNEXPECTED_EOF" cannam@89: ,"OUTBUFF_FULL" cannam@89: ,"???" /* for future */ cannam@89: ,"???" /* for future */ cannam@89: ,"???" /* for future */ cannam@89: ,"???" /* for future */ cannam@89: ,"???" /* for future */ cannam@89: ,"???" /* for future */ cannam@89: }; cannam@89: cannam@89: void flip_bit ( int bit ) cannam@89: { cannam@89: int byteno = bit / 8; cannam@89: int bitno = bit % 8; cannam@89: uchar mask = 1 << bitno; cannam@89: //fprintf ( stderr, "(byte %d bit %d mask %d)", cannam@89: // byteno, bitno, (int)mask ); cannam@89: zbuf[byteno] ^= mask; cannam@89: } cannam@89: cannam@89: int main ( int argc, char** argv ) cannam@89: { cannam@89: FILE* f; cannam@89: int r; cannam@89: int bit; cannam@89: int i; cannam@89: cannam@89: if (argc != 2) { cannam@89: fprintf ( stderr, "usage: unzcrash filename\n" ); cannam@89: return 1; cannam@89: } cannam@89: cannam@89: f = fopen ( argv[1], "r" ); cannam@89: if (!f) { cannam@89: fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] ); cannam@89: return 1; cannam@89: } cannam@89: cannam@89: nIn = fread ( inbuf, 1, M_BLOCK, f ); cannam@89: fprintf ( stderr, "%d bytes read\n", nIn ); cannam@89: cannam@89: nZ = M_BLOCK; cannam@89: r = BZ2_bzBuffToBuffCompress ( cannam@89: zbuf, &nZ, inbuf, nIn, 9, 0, 30 ); cannam@89: cannam@89: assert (r == BZ_OK); cannam@89: fprintf ( stderr, "%d after compression\n", nZ ); cannam@89: cannam@89: for (bit = 0; bit < nZ*8; bit++) { cannam@89: fprintf ( stderr, "bit %d ", bit ); cannam@89: flip_bit ( bit ); cannam@89: nOut = M_BLOCK_OUT; cannam@89: r = BZ2_bzBuffToBuffDecompress ( cannam@89: outbuf, &nOut, zbuf, nZ, 0, 0 ); cannam@89: fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] ); cannam@89: cannam@89: if (r != BZ_OK) { cannam@89: fprintf ( stderr, "\n" ); cannam@89: } else { cannam@89: if (nOut != nIn) { cannam@89: fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut ); cannam@89: return 1; cannam@89: } else { cannam@89: for (i = 0; i < nOut; i++) cannam@89: if (inbuf[i] != outbuf[i]) { cannam@89: fprintf(stderr, "mismatch at %d\n", i ); cannam@89: return 1; cannam@89: } cannam@89: if (i == nOut) fprintf(stderr, "really ok!\n" ); cannam@89: } cannam@89: } cannam@89: cannam@89: flip_bit ( bit ); cannam@89: } cannam@89: cannam@89: #if 0 cannam@89: assert (nOut == nIn); cannam@89: for (i = 0; i < nOut; i++) { cannam@89: if (inbuf[i] != outbuf[i]) { cannam@89: fprintf ( stderr, "difference at %d !\n", i ); cannam@89: return 1; cannam@89: } cannam@89: } cannam@89: #endif cannam@89: cannam@89: fprintf ( stderr, "all ok\n" ); cannam@89: return 0; cannam@89: }