Blame unzcrash.c

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