1 2 /* A test program written to test robustness to decompression of 3 corrupted data. Usage is 4 unzcrash filename 5 and the program will read the specified file, compress it (in memory), 6 and then repeatedly decompress it, each time with a different bit of 7 the compressed data inverted, so as to test all possible one-bit errors. 8 This should not cause any invalid memory accesses. If it does, 9 I want to know about it! 10 11 p.s. As you can see from the above description, the process is 12 incredibly slow. A file of size eg 5KB will cause it to run for 13 many hours. 14 */ 15 16 #include <stdio.h> 17 #include <assert.h> 18 #include "bzlib.h" 19 20 #define M_BLOCK 1000000 21 22 typedef unsigned char uchar; 23 24 #define M_BLOCK_OUT (M_BLOCK + 1000000) 25 uchar inbuf[M_BLOCK]; 26 uchar outbuf[M_BLOCK_OUT]; 27 uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)]; 28 29 int nIn, nOut, nZ; 30 31 static char *bzerrorstrings[] = { 32 "OK" 33 ,"SEQUENCE_ERROR" 34 ,"PARAM_ERROR" 35 ,"MEM_ERROR" 36 ,"DATA_ERROR" 37 ,"DATA_ERROR_MAGIC" 38 ,"IO_ERROR" 39 ,"UNEXPECTED_EOF" 40 ,"OUTBUFF_FULL" 41 ,"???" /* for future */ 42 ,"???" /* for future */ 43 ,"???" /* for future */ 44 ,"???" /* for future */ 45 ,"???" /* for future */ 46 ,"???" /* for future */ 47 }; 48 49 void flip_bit ( int bit ) 50 { 51 int byteno = bit / 8; 52 int bitno = bit % 8; 53 uchar mask = 1 << bitno; 54 //fprintf ( stderr, "(byte %d bit %d mask %d)", 55 // byteno, bitno, (int)mask ); 56 zbuf[byteno] ^= mask; 57 } 58 59 int main ( int argc, char** argv ) 60 { 61 FILE* f; 62 int r; 63 int bit; 64 int i; 65 66 if (argc != 2) { 67 fprintf ( stderr, "usage: unzcrash filename\n" ); 68 return 1; 69 } 70 71 f = fopen ( argv[1], "r" ); 72 if (!f) { 73 fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] ); 74 return 1; 75 } 76 77 nIn = fread ( inbuf, 1, M_BLOCK, f ); 78 fprintf ( stderr, "%d bytes read\n", nIn ); 79 80 nZ = M_BLOCK; 81 r = BZ2_bzBuffToBuffCompress ( 82 zbuf, &nZ, inbuf, nIn, 9, 0, 30 ); 83 84 assert (r == BZ_OK); 85 fprintf ( stderr, "%d after compression\n", nZ ); 86 87 for (bit = 0; bit < nZ*8; bit++) { 88 fprintf ( stderr, "bit %d ", bit ); 89 flip_bit ( bit ); 90 nOut = M_BLOCK_OUT; 91 r = BZ2_bzBuffToBuffDecompress ( 92 outbuf, &nOut, zbuf, nZ, 0, 0 ); 93 fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] ); 94 95 if (r != BZ_OK) { 96 fprintf ( stderr, "\n" ); 97 } else { 98 if (nOut != nIn) { 99 fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut ); 100 return 1; 101 } else { 102 for (i = 0; i < nOut; i++) 103 if (inbuf[i] != outbuf[i]) { 104 fprintf(stderr, "mismatch at %d\n", i ); 105 return 1; 106 } 107 if (i == nOut) fprintf(stderr, "really ok!\n" ); 108 } 109 } 110 111 flip_bit ( bit ); 112 } 113 114 #if 0 115 assert (nOut == nIn); 116 for (i = 0; i < nOut; i++) { 117 if (inbuf[i] != outbuf[i]) { 118 fprintf ( stderr, "difference at %d !\n", i ); 119 return 1; 120 } 121 } 122 #endif 123 124 fprintf ( stderr, "all ok\n" ); 125 return 0; 126 } 127