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