178556Sobrien 278556Sobrien/* A test program written to test robustness to decompression of 378556Sobrien corrupted data. Usage is 478556Sobrien unzcrash filename 578556Sobrien and the program will read the specified file, compress it (in memory), 678556Sobrien and then repeatedly decompress it, each time with a different bit of 778556Sobrien the compressed data inverted, so as to test all possible one-bit errors. 878556Sobrien This should not cause any invalid memory accesses. If it does, 978556Sobrien I want to know about it! 1078556Sobrien 11167974Sdelphij PS. As you can see from the above description, the process is 1278556Sobrien incredibly slow. A file of size eg 5KB will cause it to run for 1378556Sobrien many hours. 1478556Sobrien*/ 1578556Sobrien 16167974Sdelphij/* ------------------------------------------------------------------ 17167974Sdelphij This file is part of bzip2/libbzip2, a program and library for 18167974Sdelphij lossless, block-sorting data compression. 19167974Sdelphij 20351007Sdelphij bzip2/libbzip2 version 1.0.8 of 13 July 2019 21351007Sdelphij Copyright (C) 1996-2019 Julian Seward <jseward@acm.org> 22167974Sdelphij 23167974Sdelphij Please read the WARNING, DISCLAIMER and PATENTS sections in the 24167974Sdelphij README file. 25167974Sdelphij 26167974Sdelphij This program is released under the terms of the license contained 27167974Sdelphij in the file LICENSE. 28167974Sdelphij ------------------------------------------------------------------ */ 29167974Sdelphij 30167974Sdelphij 3178556Sobrien#include <stdio.h> 3278556Sobrien#include <assert.h> 3378556Sobrien#include "bzlib.h" 3478556Sobrien 3578556Sobrien#define M_BLOCK 1000000 3678556Sobrien 3778556Sobrientypedef unsigned char uchar; 3878556Sobrien 3978556Sobrien#define M_BLOCK_OUT (M_BLOCK + 1000000) 4078556Sobrienuchar inbuf[M_BLOCK]; 4178556Sobrienuchar outbuf[M_BLOCK_OUT]; 4278556Sobrienuchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)]; 4378556Sobrien 4478556Sobrienint nIn, nOut, nZ; 4578556Sobrien 4678556Sobrienstatic char *bzerrorstrings[] = { 4778556Sobrien "OK" 4878556Sobrien ,"SEQUENCE_ERROR" 4978556Sobrien ,"PARAM_ERROR" 5078556Sobrien ,"MEM_ERROR" 5178556Sobrien ,"DATA_ERROR" 5278556Sobrien ,"DATA_ERROR_MAGIC" 5378556Sobrien ,"IO_ERROR" 5478556Sobrien ,"UNEXPECTED_EOF" 5578556Sobrien ,"OUTBUFF_FULL" 5678556Sobrien ,"???" /* for future */ 5778556Sobrien ,"???" /* for future */ 5878556Sobrien ,"???" /* for future */ 5978556Sobrien ,"???" /* for future */ 6078556Sobrien ,"???" /* for future */ 6178556Sobrien ,"???" /* for future */ 6278556Sobrien}; 6378556Sobrien 6478556Sobrienvoid flip_bit ( int bit ) 6578556Sobrien{ 6678556Sobrien int byteno = bit / 8; 6778556Sobrien int bitno = bit % 8; 6878556Sobrien uchar mask = 1 << bitno; 6978556Sobrien //fprintf ( stderr, "(byte %d bit %d mask %d)", 7078556Sobrien // byteno, bitno, (int)mask ); 7178556Sobrien zbuf[byteno] ^= mask; 7278556Sobrien} 7378556Sobrien 7478556Sobrienint main ( int argc, char** argv ) 7578556Sobrien{ 7678556Sobrien FILE* f; 7778556Sobrien int r; 7878556Sobrien int bit; 7978556Sobrien int i; 8078556Sobrien 8178556Sobrien if (argc != 2) { 8278556Sobrien fprintf ( stderr, "usage: unzcrash filename\n" ); 8378556Sobrien return 1; 8478556Sobrien } 8578556Sobrien 8678556Sobrien f = fopen ( argv[1], "r" ); 8778556Sobrien if (!f) { 8878556Sobrien fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] ); 8978556Sobrien return 1; 9078556Sobrien } 9178556Sobrien 9278556Sobrien nIn = fread ( inbuf, 1, M_BLOCK, f ); 9378556Sobrien fprintf ( stderr, "%d bytes read\n", nIn ); 9478556Sobrien 9578556Sobrien nZ = M_BLOCK; 9678556Sobrien r = BZ2_bzBuffToBuffCompress ( 9778556Sobrien zbuf, &nZ, inbuf, nIn, 9, 0, 30 ); 9878556Sobrien 9978556Sobrien assert (r == BZ_OK); 10078556Sobrien fprintf ( stderr, "%d after compression\n", nZ ); 10178556Sobrien 10278556Sobrien for (bit = 0; bit < nZ*8; bit++) { 10378556Sobrien fprintf ( stderr, "bit %d ", bit ); 10478556Sobrien flip_bit ( bit ); 10578556Sobrien nOut = M_BLOCK_OUT; 10678556Sobrien r = BZ2_bzBuffToBuffDecompress ( 10778556Sobrien outbuf, &nOut, zbuf, nZ, 0, 0 ); 10878556Sobrien fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] ); 10978556Sobrien 11078556Sobrien if (r != BZ_OK) { 11178556Sobrien fprintf ( stderr, "\n" ); 11278556Sobrien } else { 11378556Sobrien if (nOut != nIn) { 11478556Sobrien fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut ); 11578556Sobrien return 1; 11678556Sobrien } else { 11778556Sobrien for (i = 0; i < nOut; i++) 11878556Sobrien if (inbuf[i] != outbuf[i]) { 11978556Sobrien fprintf(stderr, "mismatch at %d\n", i ); 12078556Sobrien return 1; 12178556Sobrien } 12278556Sobrien if (i == nOut) fprintf(stderr, "really ok!\n" ); 12378556Sobrien } 12478556Sobrien } 12578556Sobrien 12678556Sobrien flip_bit ( bit ); 12778556Sobrien } 12878556Sobrien 12978556Sobrien#if 0 13078556Sobrien assert (nOut == nIn); 13178556Sobrien for (i = 0; i < nOut; i++) { 13278556Sobrien if (inbuf[i] != outbuf[i]) { 13378556Sobrien fprintf ( stderr, "difference at %d !\n", i ); 13478556Sobrien return 1; 13578556Sobrien } 13678556Sobrien } 13778556Sobrien#endif 13878556Sobrien 13978556Sobrien fprintf ( stderr, "all ok\n" ); 14078556Sobrien return 0; 14178556Sobrien} 142