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