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