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