xref: /netbsd-src/external/bsd/bzip2/dist/unzcrash.c (revision c12ab3f1404d3e6320413d6099c78880423d6a49)
1*c12ab3f1Smaya /*	$NetBSD: unzcrash.c,v 1.1.1.3 2019/07/21 11:35:30 maya Exp $	*/
24f9a1459Swiz 
34f9a1459Swiz 
44f9a1459Swiz /* A test program written to test robustness to decompression of
54f9a1459Swiz    corrupted data.  Usage is
64f9a1459Swiz        unzcrash filename
74f9a1459Swiz    and the program will read the specified file, compress it (in memory),
84f9a1459Swiz    and then repeatedly decompress it, each time with a different bit of
94f9a1459Swiz    the compressed data inverted, so as to test all possible one-bit errors.
104f9a1459Swiz    This should not cause any invalid memory accesses.  If it does,
114f9a1459Swiz    I want to know about it!
124f9a1459Swiz 
134f9a1459Swiz    PS.  As you can see from the above description, the process is
144f9a1459Swiz    incredibly slow.  A file of size eg 5KB will cause it to run for
154f9a1459Swiz    many hours.
164f9a1459Swiz */
174f9a1459Swiz 
184f9a1459Swiz /* ------------------------------------------------------------------
194f9a1459Swiz    This file is part of bzip2/libbzip2, a program and library for
204f9a1459Swiz    lossless, block-sorting data compression.
214f9a1459Swiz 
22*c12ab3f1Smaya    bzip2/libbzip2 version 1.0.8 of 13 July 2019
23*c12ab3f1Smaya    Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
244f9a1459Swiz 
254f9a1459Swiz    Please read the WARNING, DISCLAIMER and PATENTS sections in the
264f9a1459Swiz    README file.
274f9a1459Swiz 
284f9a1459Swiz    This program is released under the terms of the license contained
294f9a1459Swiz    in the file LICENSE.
304f9a1459Swiz    ------------------------------------------------------------------ */
314f9a1459Swiz 
324f9a1459Swiz 
334f9a1459Swiz #include <stdio.h>
344f9a1459Swiz #include <assert.h>
354f9a1459Swiz #include "bzlib.h"
364f9a1459Swiz 
374f9a1459Swiz #define M_BLOCK 1000000
384f9a1459Swiz 
394f9a1459Swiz typedef unsigned char uchar;
404f9a1459Swiz 
414f9a1459Swiz #define M_BLOCK_OUT (M_BLOCK + 1000000)
424f9a1459Swiz uchar inbuf[M_BLOCK];
434f9a1459Swiz uchar outbuf[M_BLOCK_OUT];
444f9a1459Swiz uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
454f9a1459Swiz 
464f9a1459Swiz int nIn, nOut, nZ;
474f9a1459Swiz 
484f9a1459Swiz static char *bzerrorstrings[] = {
494f9a1459Swiz        "OK"
504f9a1459Swiz       ,"SEQUENCE_ERROR"
514f9a1459Swiz       ,"PARAM_ERROR"
524f9a1459Swiz       ,"MEM_ERROR"
534f9a1459Swiz       ,"DATA_ERROR"
544f9a1459Swiz       ,"DATA_ERROR_MAGIC"
554f9a1459Swiz       ,"IO_ERROR"
564f9a1459Swiz       ,"UNEXPECTED_EOF"
574f9a1459Swiz       ,"OUTBUFF_FULL"
584f9a1459Swiz       ,"???"   /* for future */
594f9a1459Swiz       ,"???"   /* for future */
604f9a1459Swiz       ,"???"   /* for future */
614f9a1459Swiz       ,"???"   /* for future */
624f9a1459Swiz       ,"???"   /* for future */
634f9a1459Swiz       ,"???"   /* for future */
644f9a1459Swiz };
654f9a1459Swiz 
flip_bit(int bit)664f9a1459Swiz void flip_bit ( int bit )
674f9a1459Swiz {
684f9a1459Swiz    int byteno = bit / 8;
694f9a1459Swiz    int bitno  = bit % 8;
704f9a1459Swiz    uchar mask = 1 << bitno;
714f9a1459Swiz    //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
724f9a1459Swiz    //          byteno, bitno, (int)mask );
734f9a1459Swiz    zbuf[byteno] ^= mask;
744f9a1459Swiz }
754f9a1459Swiz 
main(int argc,char ** argv)764f9a1459Swiz int main ( int argc, char** argv )
774f9a1459Swiz {
784f9a1459Swiz    FILE* f;
794f9a1459Swiz    int   r;
804f9a1459Swiz    int   bit;
814f9a1459Swiz    int   i;
824f9a1459Swiz 
834f9a1459Swiz    if (argc != 2) {
844f9a1459Swiz       fprintf ( stderr, "usage: unzcrash filename\n" );
854f9a1459Swiz       return 1;
864f9a1459Swiz    }
874f9a1459Swiz 
884f9a1459Swiz    f = fopen ( argv[1], "r" );
894f9a1459Swiz    if (!f) {
904f9a1459Swiz       fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
914f9a1459Swiz       return 1;
924f9a1459Swiz    }
934f9a1459Swiz 
944f9a1459Swiz    nIn = fread ( inbuf, 1, M_BLOCK, f );
954f9a1459Swiz    fprintf ( stderr, "%d bytes read\n", nIn );
964f9a1459Swiz 
974f9a1459Swiz    nZ = M_BLOCK;
984f9a1459Swiz    r = BZ2_bzBuffToBuffCompress (
994f9a1459Swiz          zbuf, &nZ, inbuf, nIn, 9, 0, 30 );
1004f9a1459Swiz 
1014f9a1459Swiz    assert (r == BZ_OK);
1024f9a1459Swiz    fprintf ( stderr, "%d after compression\n", nZ );
1034f9a1459Swiz 
1044f9a1459Swiz    for (bit = 0; bit < nZ*8; bit++) {
1054f9a1459Swiz       fprintf ( stderr, "bit %d  ", bit );
1064f9a1459Swiz       flip_bit ( bit );
1074f9a1459Swiz       nOut = M_BLOCK_OUT;
1084f9a1459Swiz       r = BZ2_bzBuffToBuffDecompress (
1094f9a1459Swiz             outbuf, &nOut, zbuf, nZ, 0, 0 );
1104f9a1459Swiz       fprintf ( stderr, " %d  %s ", r, bzerrorstrings[-r] );
1114f9a1459Swiz 
1124f9a1459Swiz       if (r != BZ_OK) {
1134f9a1459Swiz          fprintf ( stderr, "\n" );
1144f9a1459Swiz       } else {
1154f9a1459Swiz          if (nOut != nIn) {
1164f9a1459Swiz            fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
1174f9a1459Swiz            return 1;
1184f9a1459Swiz          } else {
1194f9a1459Swiz            for (i = 0; i < nOut; i++)
1204f9a1459Swiz              if (inbuf[i] != outbuf[i]) {
1214f9a1459Swiz                 fprintf(stderr, "mismatch at %d\n", i );
1224f9a1459Swiz                 return 1;
1234f9a1459Swiz            }
1244f9a1459Swiz            if (i == nOut) fprintf(stderr, "really ok!\n" );
1254f9a1459Swiz          }
1264f9a1459Swiz       }
1274f9a1459Swiz 
1284f9a1459Swiz       flip_bit ( bit );
1294f9a1459Swiz    }
1304f9a1459Swiz 
1314f9a1459Swiz #if 0
1324f9a1459Swiz    assert (nOut == nIn);
1334f9a1459Swiz    for (i = 0; i < nOut; i++) {
1344f9a1459Swiz      if (inbuf[i] != outbuf[i]) {
1354f9a1459Swiz         fprintf ( stderr, "difference at %d !\n", i );
1364f9a1459Swiz         return 1;
1374f9a1459Swiz      }
1384f9a1459Swiz    }
1394f9a1459Swiz #endif
1404f9a1459Swiz 
1414f9a1459Swiz    fprintf ( stderr, "all ok\n" );
1424f9a1459Swiz    return 0;
1434f9a1459Swiz }
144