From e6c763bfbc62868041586906479f63fa8c14bc2a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 21 Feb 2025 11:16:43 +0100 Subject: [PATCH] Merging upstream version 1.15~pre1. Signed-off-by: Daniel Baumann --- ChangeLog | 8 + INSTALL | 2 +- Makefile.in | 9 +- NEWS | 27 +- README | 11 +- configure | 10 +- decoder.cc | 16 +- decoder.h | 8 +- doc/lziprecover.1 | 2 +- doc/lziprecover.info | 165 +++++---- doc/lziprecover.texinfo | 133 +++++--- file_index.cc | 136 +++++++- file_index.h | 35 +- lzip.h | 12 +- main.cc | 1 - merge.cc | 390 ++++++++++++---------- range_dec.cc | 19 +- repair.cc | 123 ++++--- split.cc | 5 +- testsuite/check.sh | 164 ++++++--- testsuite/{fox5_bad.lz => fox5.lz} | Bin 400 -> 400 bytes testsuite/fox5_bad1.lz | Bin 0 -> 400 bytes testsuite/{fox5_bad.txt => fox5_bad1.txt} | 2 +- testsuite/{fox5_bad.lz => fox5_bad2.lz} | Bin 400 -> 400 bytes testsuite/fox5_bad3.lz | Bin 0 -> 400 bytes testsuite/fox5_bad4.lz | Bin 0 -> 400 bytes testsuite/fox5_bad5.lz | Bin 0 -> 400 bytes testsuite/test.txt.lz | Bin 0 -> 11518 bytes testsuite/test_bad1.lz | Bin 11548 -> 11518 bytes testsuite/test_bad2.lz | Bin 11548 -> 11518 bytes testsuite/test_bad3.lz | Bin 11548 -> 11518 bytes testsuite/test_bad4.lz | Bin 11548 -> 11518 bytes testsuite/test_bad5.lz | Bin 11548 -> 11518 bytes testsuite/test_v0.lz | Bin 11540 -> 0 bytes testsuite/test_v1.lz | Bin 11548 -> 0 bytes testsuite/unzcrash.cc | 10 +- 36 files changed, 793 insertions(+), 495 deletions(-) copy testsuite/{fox5_bad.lz => fox5.lz} (84%) create mode 100644 testsuite/fox5_bad1.lz rename testsuite/{fox5_bad.txt => fox5_bad1.txt} (71%) rename testsuite/{fox5_bad.lz => fox5_bad2.lz} (68%) create mode 100644 testsuite/fox5_bad3.lz create mode 100644 testsuite/fox5_bad4.lz create mode 100644 testsuite/fox5_bad5.lz create mode 100644 testsuite/test.txt.lz delete mode 100644 testsuite/test_v0.lz delete mode 100644 testsuite/test_v1.lz diff --git a/ChangeLog b/ChangeLog index acbbb44..f2f71e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-06-17 Antonio Diaz Diaz + + * Version 1.15-pre1 released. + * repair.cc: Repair multi-member files with up to one byte error + per member. + * merge.cc: Merge multi-member files. + * Added chapters 'Repairing Files' and 'Merging Files' to the manual. + 2013-05-31 Antonio Diaz Diaz * Version 1.14 released. diff --git a/INSTALL b/INSTALL index cc04763..465a543 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ Requirements ------------ You will need a C++ compiler. -I use gcc 4.8.0 and 3.3.6, but the code should compile with any +I use gcc 4.8.1 and 3.3.6, but the code should compile with any standards compliant compiler. Gcc is available at http://gcc.gnu.org. diff --git a/Makefile.in b/Makefile.in index e769333..bb69807 100644 --- a/Makefile.in +++ b/Makefile.in @@ -42,7 +42,7 @@ file_index.o : lzip.h file_index.h main.o : arg_parser.h lzip.h decoder.h merge.o : lzip.h decoder.h file_index.h range_dec.o : lzip.h decoder.h file_index.h -repair.o : lzip.h +repair.o : lzip.h file_index.h split.o : lzip.h unzcrash.o : arg_parser.h Makefile @@ -115,12 +115,13 @@ dist : doc $(DISTNAME)/doc/$(pkgname).info \ $(DISTNAME)/doc/$(pkgname).texinfo \ $(DISTNAME)/testsuite/check.sh \ - $(DISTNAME)/testsuite/fox5_bad.lz \ - $(DISTNAME)/testsuite/fox5_bad.txt \ + $(DISTNAME)/testsuite/fox5.lz \ + $(DISTNAME)/testsuite/fox5_bad[1-5].lz \ + $(DISTNAME)/testsuite/fox5_bad1.txt \ $(DISTNAME)/testsuite/test.txt \ + $(DISTNAME)/testsuite/test.txt.lz \ $(DISTNAME)/testsuite/test921-1921.txt \ $(DISTNAME)/testsuite/test_bad[1-5].lz \ - $(DISTNAME)/testsuite/test_v[01].lz \ $(DISTNAME)/testsuite/unzcrash.cc \ $(DISTNAME)/*.h \ $(DISTNAME)/*.cc diff --git a/NEWS b/NEWS index 1558dc8..70b39a1 100644 --- a/NEWS +++ b/NEWS @@ -1,23 +1,10 @@ -Changes in version 1.14: +Changes in version 1.15: -The new option "-i, --ignore-errors", which in conjunction with "-D" -decompresses all the recoverable data in all members of a file without -having to split it first, has been added. +Lziprecover can now repair multi-member files with up to one byte error +per member, without having to split them first. -Option "-l, --list" now accepts more than one file. +Lziprecover can now merge multi-member files without having to split +them first even if some copies have the header and the trailer damaged. -Decompression time has been reduced by 12%. - -"--split" now uses as few digits as possible in the names of the files -produced, depending on the number of members in the input file. - -"--split" in verbose mode now shows the names of files being created. - -When decompressing or testing, file version is now shown only if -verbosity >= 4. - -"configure" now accepts options with a separate argument. - -The target "install-as-lzip" has been added to the Makefile. - -The target "install-bin" has been added to the Makefile. +The chapters "Repairing Files" and "Merging Files" have been added to +the manual. diff --git a/README b/README index e5b3641..e96690f 100644 --- a/README +++ b/README @@ -2,14 +2,15 @@ Description Lziprecover is a data recovery tool and decompressor for files in the lzip compressed data format (.lz) able to repair slightly damaged files, -recover badly damaged files from two or more copies, extract undamaged -members from multi-member files, decompress files and test integrity of -files. +recover badly damaged files from two or more copies, extract data from +damaged files, decompress files and test integrity of files. Lziprecover is able to recover or decompress files produced by any of the compressors in the lzip family; lzip, plzip, minilzip/lzlib, clzip -and pdlzip. This recovery capability contributes to make the lzip format -one of the best options for long-term data archiving. +and pdlzip. It makes lzip files resistant to bit-flip, one of the most +common forms of data corruption, and its recovery capabilities +contribute to make of the lzip format one of the best options for +long-term data archiving. Lziprecover is able to efficiently extract a range of bytes from a multi-member file, because it only decompresses the members containing diff --git a/configure b/configure index 7faf560..da0011b 100755 --- a/configure +++ b/configure @@ -6,7 +6,7 @@ # to copy, distribute and modify it. pkgname=lziprecover -pkgversion=1.14 +pkgversion=1.15-pre1 progname=lziprecover srctrigger=doc/lziprecover.texinfo @@ -100,7 +100,7 @@ while [ $# != 0 ] ; do *=* | *-*-*) ;; *) echo "configure: unrecognized option: '${option}'" 1>&2 - echo "Try 'configure --help' for more information." + echo "Try 'configure --help' for more information." 1>&2 exit 1 ;; esac @@ -125,10 +125,8 @@ if [ -z "${srcdir}" ] ; then fi if [ ! -r "${srcdir}/${srctrigger}" ] ; then - exec 1>&2 - echo - echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" - echo "configure: (At least ${srctrigger} is missing)." + echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" 1>&2 + echo "configure: (At least ${srctrigger} is missing)." 1>&2 exit 1 fi diff --git a/decoder.cc b/decoder.cc index 8ed1aae..497471c 100644 --- a/decoder.cc +++ b/decoder.cc @@ -126,7 +126,7 @@ void LZ_decoder::flush_data() bool LZ_decoder::verify_trailer( const Pretty_print & pp ) const { File_trailer trailer; - const int trailer_size = File_trailer::size( member_version ); + const int trailer_size = File_trailer::size; const unsigned long long member_size = rdec.member_position() + trailer_size; bool error = false; @@ -144,8 +144,6 @@ bool LZ_decoder::verify_trailer( const Pretty_print & pp ) const while( size < trailer_size ) trailer.data[size++] = 0; } - if( member_version == 0 ) trailer.member_size( member_size ); - if( !rdec.code_is_zero() ) { error = true; @@ -220,7 +218,7 @@ int LZ_decoder::decode_member( const Pretty_print & pp ) while( !rdec.finished() ) { const int pos_state = data_position() & pos_state_mask; - if( rdec.decode_bit( bm_match[state()][pos_state] ) == 0 ) + if( rdec.decode_bit( bm_match[state()][pos_state] ) == 0 ) // 1st bit { const uint8_t prev_byte = get_prev_byte(); if( state.is_char() ) @@ -233,21 +231,21 @@ int LZ_decoder::decode_member( const Pretty_print & pp ) else { int len; - if( rdec.decode_bit( bm_rep[state()] ) == 1 ) + if( rdec.decode_bit( bm_rep[state()] ) == 1 ) // 2nd bit { - if( rdec.decode_bit( bm_rep0[state()] ) == 0 ) + if( rdec.decode_bit( bm_rep0[state()] ) == 0 ) // 3rd bit { - if( rdec.decode_bit( bm_len[state()][pos_state] ) == 0 ) + if( rdec.decode_bit( bm_len[state()][pos_state] ) == 0 ) // 4th bit { state.set_short_rep(); put_byte( get_byte( rep0 ) ); continue; } } else { unsigned distance; - if( rdec.decode_bit( bm_rep1[state()] ) == 0 ) + if( rdec.decode_bit( bm_rep1[state()] ) == 0 ) // 4th bit distance = rep1; else { - if( rdec.decode_bit( bm_rep2[state()] ) == 0 ) + if( rdec.decode_bit( bm_rep2[state()] ) == 0 ) // 5th bit distance = rep2; else { distance = rep3; rep3 = rep2; } diff --git a/decoder.h b/decoder.h index a153bcb..0c4697b 100644 --- a/decoder.h +++ b/decoder.h @@ -176,11 +176,11 @@ public: match_byte <<= 1; const int match_bit = match_byte & 0x100; const int bit = decode_bit( bm1[match_bit+symbol] ); - symbol = ( symbol << 1 ) + bit; + symbol = ( symbol << 1 ) | bit; if( match_bit != bit << 8 ) { while( symbol < 0x100 ) - symbol = ( symbol << 1 ) + decode_bit( bm[symbol] ); + symbol = ( symbol << 1 ) | decode_bit( bm[symbol] ); break; } } @@ -213,7 +213,6 @@ class LZ_decoder int stream_pos; // first byte not yet written to file uint32_t crc_; const int outfd; // output file descriptor - const int member_version; unsigned long long stream_position() const { return partial_data_pos + stream_pos; } void flush_data(); @@ -273,8 +272,7 @@ public: pos( 0 ), stream_pos( 0 ), crc_( 0xFFFFFFFFU ), - outfd( ofd ), - member_version( header.version() ) + outfd( ofd ) { buffer[buffer_size-1] = 0; } // prev_byte of first_byte ~LZ_decoder() { delete[] buffer; } diff --git a/doc/lziprecover.1 b/doc/lziprecover.1 index f62094a..fce7640 100644 --- a/doc/lziprecover.1 +++ b/doc/lziprecover.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH LZIPRECOVER "1" "May 2013" "Lziprecover 1.14" "User Commands" +.TH LZIPRECOVER "1" "June 2013" "Lziprecover 1.15-pre1" "User Commands" .SH NAME Lziprecover \- recovers data from damaged lzip files .SH SYNOPSIS diff --git a/doc/lziprecover.info b/doc/lziprecover.info index 83267d5..0d39838 100644 --- a/doc/lziprecover.info +++ b/doc/lziprecover.info @@ -12,16 +12,18 @@ File: lziprecover.info, Node: Top, Next: Introduction, Up: (dir) Lziprecover Manual ****************** -This manual is for Lziprecover (version 1.14, 31 May 2013). +This manual is for Lziprecover (version 1.15-pre1, 17 June 2013). * Menu: -* Introduction:: Purpose and features of lziprecover -* Invoking Lziprecover:: Command line interface -* File Format:: Detailed format of the compressed file -* Examples:: A small tutorial with examples -* Problems:: Reporting bugs -* Concept Index:: Index of concepts +* Introduction:: Purpose and features of lziprecover +* Invoking Lziprecover:: Command line interface +* Repairing Files:: Fixing bit-flip and similar errors +* Merging Files:: Fixing several damaged copies +* File Format:: Detailed format of the compressed file +* Examples:: A small tutorial with examples +* Problems:: Reporting bugs +* Concept Index:: Index of concepts Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz. @@ -37,14 +39,15 @@ File: lziprecover.info, Node: Introduction, Next: Invoking Lziprecover, Prev: Lziprecover is a data recovery tool and decompressor for files in the lzip compressed data format (.lz) able to repair slightly damaged files, -recover badly damaged files from two or more copies, extract undamaged -members from multi-member files, decompress files and test integrity of -files. +recover badly damaged files from two or more copies, extract data from +damaged files, decompress files and test integrity of files. Lziprecover is able to recover or decompress files produced by any of the compressors in the lzip family; lzip, plzip, minilzip/lzlib, clzip -and pdlzip. This recovery capability contributes to make the lzip format -one of the best options for long-term data archiving. +and pdlzip. It makes lzip files resistant to bit-flip, one of the most +common forms of data corruption, and its recovery capabilities +contribute to make of the lzip format one of the best options for +long-term data archiving. Lziprecover is able to efficiently extract a range of bytes from a multi-member file, because it only decompresses the members containing @@ -61,19 +64,22 @@ damaged files themselves are never modified. When decompressing or testing file integrity, lziprecover behaves like lzip or lunzip. - If the files are too damaged for lziprecover to repair them, data -from damaged members can be partially recovered writing it to stdout as -shown in the following example (the resulting file may contain some -garbage data at the end): + If a file is too damaged for lziprecover to repair it, all the +recoverable data in all members of the file can be extracted with the +following command (the resulting file may contain errors and some +garbage data may be produced at the end of each member): - lziprecover -cd rec01file.lz > rec01file + lziprecover -D0 -i -o file -q file.lz If the cause of file corruption is damaged media, the combination GNU ddrescue + lziprecover is the best option for recovering data from multiple damaged copies. *Note ddrescue-example::, for an example. + Lziprecover is not a replacement for regular backups, but a last +line of defense for the case where the backups are also damaged. +  -File: lziprecover.info, Node: Invoking Lziprecover, Next: File Format, Prev: Introduction, Up: Top +File: lziprecover.info, Node: Invoking Lziprecover, Next: Repairing Files, Prev: Introduction, Up: Top 2 Invoking Lziprecover ********************** @@ -141,18 +147,10 @@ The format for running lziprecover is: `-m' `--merge' Try to produce a correct file merging the good parts of two or more - damaged copies. The copies must be single-member files. The merge - will fail if the copies have too many damaged areas or if the same - byte is damaged in all copies. If successful, a repaired copy is - written to the file `FILE_fixed.lz'. The exit status is 0 if the - file could be repaired, 2 otherwise. - - To give you an idea of its possibilities, when merging two copies - each of them with one damaged area affecting 1 percent of the - copy, the probability of obtaining a correct file is about 98 - percent. With three such copies the probability rises to 99.97 - percent. For large files with small errors, the probability - approaches 100 percent even with only two copies. + damaged copies. If successful, a repaired copy is written to the + file `FILE_fixed.lz'. The exit status is 0 if a correct file could + be produced, 2 otherwise. See the chapter Merging Files (*note + Merging Files::) for a complete description of the merge mode. `-o FILE' `--output=FILE' @@ -168,10 +166,12 @@ The format for running lziprecover is: `-R' `--repair' - Try to repair a small error, affecting only one byte, in a - single-member FILE. If successful, a repaired copy is written to - the file `FILE_fixed.lz'. `FILE' is not modified at all. The exit - status is 0 if the file could be repaired, 2 otherwise. + Try to repair a file with small errors (up to one byte error per + member). If successful, a repaired copy is written to the file + `FILE_fixed.lz'. `FILE' is not modified at all. The exit status + is 0 if the file could be repaired, 2 otherwise. See the chapter + Repairing Files (*note Repairing Files::) for a complete + description of the repair mode. `-s' `--split' @@ -227,9 +227,52 @@ invalid input file, 3 for an internal consistency error (eg, bug) which caused lziprecover to panic.  -File: lziprecover.info, Node: File Format, Next: Examples, Prev: Invoking Lziprecover, Up: Top +File: lziprecover.info, Node: Repairing Files, Next: Merging Files, Prev: Invoking Lziprecover, Up: Top -3 File Format +3 Repairing Files +***************** + +Lziprecover is able to repair files with small errors (up to one byte +error per member). The error may be located anywhere in the file except +in the header (first 6 bytes of each member) or in the `Member size' +field of the trailer (last 8 bytes of each member). This makes lzip +files resistant to bit-flip, one of the most common forms of data +corruption. + + Bit-flip happens when one bit in the file is changed from 0 to 1 or +vice versa. It may be caused by bad RAM or even by natural radiation. I +have seen a case of bit-flip in a file stored in an USB flash drive. + + +File: lziprecover.info, Node: Merging Files, Next: File Format, Prev: Repairing Files, Up: Top + +4 Merging Files +*************** + +If you have several copies of a file but all of them are too damaged to +repair them (*note Repairing Files::), lziprecover can try to produce a +correct file merging the good parts of the damaged copies. + + The merge may succeed even if some copies of the file have all the +headers and trailers damaged, as long as there is at least one copy of +every header and trailer intact, even if they are in different copies of +the file. + + The merge will fail if the damaged areas overlap (at least one byte +is damaged in all copies), or are adjacent and the boundary can't be +determined, or if the copies have too many damaged areas. + + To give you an idea of its possibilities, when merging two copies +each of them with one damaged area affecting 1 percent of the copy, the +probability of obtaining a correct file is about 98 percent. With three +such copies the probability rises to 99.97 percent. For large files with +small errors, the probability approaches 100 percent even with only two +copies. + + +File: lziprecover.info, Node: File Format, Next: Examples, Prev: Merging Files, Up: Top + +5 File Format ************* Perfection is reached, not when there is no longer anything to add, but @@ -302,7 +345,7 @@ additional information before, between, or after them.  File: lziprecover.info, Node: Examples, Next: Problems, Prev: File Format, Up: Top -4 A small tutorial with examples +6 A small tutorial with examples ******************************** Example 1: Restore a regular file from its compressed version @@ -329,9 +372,8 @@ to decompressed byte 15000 (5000 bytes are produced). lziprecover -D 10000-15000 file.lz -Example 5: Repair a one-byte corruption in the single-member file -`file.lz'. (Indented lines are abridged error messages from -lziprecover). +Example 5: Repair small errors in the file `file.lz'. (Indented lines +are abridged diagnostic messages from lziprecover). lziprecover -v -R file.lz Copy of input file repaired successfully. @@ -365,31 +407,16 @@ error-checked merging of copies (*Note GNU ddrescue manual: Example 8: Recover the first volume of those created with the command `lzip -b 32MiB -S 650MB big_db' from two copies, `big_db1_00001.lz' and `big_db2_00001.lz', with member 07 damaged in the first copy, member 18 -damaged in the second copy, and member 12 damaged in both copies. Two -correct copies are produced and compared. +damaged in the second copy, and member 12 damaged in both copies. The +correct file produced is saved in `big_db_00001.lz'. - lziprecover -s big_db1_00001.lz - lziprecover -s big_db2_00001.lz - lziprecover -t rec*big_db1_00001.lz - rec07big_db1_00001.lz: crc mismatch - rec12big_db1_00001.lz: crc mismatch - lziprecover -t rec*big_db2_00001.lz - rec12big_db2_00001.lz: crc mismatch - rec18big_db2_00001.lz: crc mismatch - lziprecover -m -v rec12big_db1_00001.lz rec12big_db2_00001.lz + lziprecover -m -v -o big_db_00001.lz big_db1_00001.lz big_db2_00001.lz Input files merged successfully - cp rec07big_db2_00001.lz rec07big_db1_00001.lz - cp rec12big_db1_00001_fixed.lz rec12big_db1_00001.lz - cp rec12big_db1_00001_fixed.lz rec12big_db2_00001.lz - cp rec18big_db1_00001.lz rec18big_db2_00001.lz - cat rec*big_db1_00001.lz > big_db3_00001.lz - cat rec*big_db2_00001.lz > big_db4_00001.lz - zcmp big_db3_00001.lz big_db4_00001.lz  File: lziprecover.info, Node: Problems, Next: Concept Index, Prev: Examples, Up: Top -5 Reporting Bugs +7 Reporting Bugs **************** There are probably bugs in lziprecover. There are certainly errors and @@ -415,19 +442,23 @@ Concept Index * file format: File Format. (line 6) * getting help: Problems. (line 6) * introduction: Introduction. (line 6) -* invoking lziprecover: Invoking Lziprecover. (line 6) +* invoking: Invoking Lziprecover. (line 6) +* merging files: Merging Files. (line 6) +* repairing files: Repairing Files. (line 6)  Tag Table: Node: Top231 -Node: Introduction901 -Node: Invoking Lziprecover2685 -Node: File Format8447 -Node: Examples10938 -Ref: ddrescue-example12158 -Node: Problems13938 -Node: Concept Index14488 +Node: Introduction1032 +Node: Invoking Lziprecover3052 +Node: Repairing Files8489 +Node: Merging Files9208 +Node: File Format10338 +Node: Examples12822 +Ref: ddrescue-example14024 +Node: Problems15134 +Node: Concept Index15684  End Tag Table diff --git a/doc/lziprecover.texinfo b/doc/lziprecover.texinfo index 142cdae..54834e9 100644 --- a/doc/lziprecover.texinfo +++ b/doc/lziprecover.texinfo @@ -6,8 +6,8 @@ @finalout @c %**end of header -@set UPDATED 31 May 2013 -@set VERSION 1.14 +@set UPDATED 17 June 2013 +@set VERSION 1.15-pre1 @dircategory Data Compression @direntry @@ -35,12 +35,14 @@ This manual is for Lziprecover (version @value{VERSION}, @value{UPDATED}). @menu -* Introduction:: Purpose and features of lziprecover -* Invoking Lziprecover:: Command line interface -* File Format:: Detailed format of the compressed file -* Examples:: A small tutorial with examples -* Problems:: Reporting bugs -* Concept Index:: Index of concepts +* Introduction:: Purpose and features of lziprecover +* Invoking Lziprecover:: Command line interface +* Repairing Files:: Fixing bit-flip and similar errors +* Merging Files:: Fixing several damaged copies +* File Format:: Detailed format of the compressed file +* Examples:: A small tutorial with examples +* Problems:: Reporting bugs +* Concept Index:: Index of concepts @end menu @sp 1 @@ -56,14 +58,15 @@ to copy, distribute and modify it. Lziprecover is a data recovery tool and decompressor for files in the lzip compressed data format (.lz) able to repair slightly damaged files, -recover badly damaged files from two or more copies, extract undamaged -members from multi-member files, decompress files and test integrity of -files. +recover badly damaged files from two or more copies, extract data from +damaged files, decompress files and test integrity of files. Lziprecover is able to recover or decompress files produced by any of the compressors in the lzip family; lzip, plzip, minilzip/lzlib, clzip -and pdlzip. This recovery capability contributes to make the lzip format -one of the best options for long-term data archiving. +and pdlzip. It makes lzip files resistant to bit-flip, one of the most +common forms of data corruption, and its recovery capabilities +contribute to make of the lzip format one of the best options for +long-term data archiving. Lziprecover is able to efficiently extract a range of bytes from a multi-member file, because it only decompresses the members containing @@ -80,23 +83,26 @@ damaged files themselves are never modified. When decompressing or testing file integrity, lziprecover behaves like lzip or lunzip. -If the files are too damaged for lziprecover to repair them, data from -damaged members can be partially recovered writing it to stdout as shown -in the following example (the resulting file may contain some garbage -data at the end): +If a file is too damaged for lziprecover to repair it, all the +recoverable data in all members of the file can be extracted with the +following command (the resulting file may contain errors and some +garbage data may be produced at the end of each member): @example -lziprecover -cd rec01file.lz > rec01file +lziprecover -D0 -i -o file -q file.lz @end example If the cause of file corruption is damaged media, the combination @w{GNU ddrescue + lziprecover} is the best option for recovering data from multiple damaged copies. @xref{ddrescue-example}, for an example. +Lziprecover is not a replacement for regular backups, but a last line of +defense for the case where the backups are also damaged. + @node Invoking Lziprecover @chapter Invoking Lziprecover -@cindex invoking lziprecover +@cindex invoking The format for running lziprecover is: @@ -164,18 +170,10 @@ information about the members in the file. @item -m @itemx --merge Try to produce a correct file merging the good parts of two or more -damaged copies. The copies must be single-member files. The merge will -fail if the copies have too many damaged areas or if the same byte is -damaged in all copies. If successful, a repaired copy is written to the -file @samp{@var{file}_fixed.lz}. The exit status is 0 if the file could -be repaired, 2 otherwise. - -To give you an idea of its possibilities, when merging two copies each -of them with one damaged area affecting 1 percent of the copy, the -probability of obtaining a correct file is about 98 percent. With three -such copies the probability rises to 99.97 percent. For large files with -small errors, the probability approaches 100 percent even with only two -copies. +damaged copies. If successful, a repaired copy is written to the file +@samp{@var{file}_fixed.lz}. The exit status is 0 if a correct file could +be produced, 2 otherwise. See the chapter Merging Files (@pxref{Merging +Files}) for a complete description of the merge mode. @item -o @var{file} @itemx --output=@var{file} @@ -192,10 +190,12 @@ Quiet operation. Suppress all messages. @item -R @itemx --repair -Try to repair a small error, affecting only one byte, in a single-member -@var{file}. If successful, a repaired copy is written to the file +Try to repair a file with small errors (up to one byte error per member). +If successful, a repaired copy is written to the file @samp{@var{file}_fixed.lz}. @samp{@var{file}} is not modified at all. The exit status is 0 if the file could be repaired, 2 otherwise. +See the chapter Repairing Files (@pxref{Repairing Files}) for a complete +description of the repair mode. @item -s @itemx --split @@ -252,6 +252,47 @@ invalid input file, 3 for an internal consistency error (eg, bug) which caused lziprecover to panic. +@node Repairing Files +@chapter Repairing Files +@cindex repairing files + +Lziprecover is able to repair files with small errors (up to one byte +error per member). The error may be located anywhere in the file except +in the header (first 6 bytes of each member) or in the @samp{Member +size} field of the trailer (last 8 bytes of each member). This makes +lzip files resistant to bit-flip, one of the most common forms of data +corruption. + +Bit-flip happens when one bit in the file is changed from 0 to 1 or vice +versa. It may be caused by bad RAM or even by natural radiation. I have +seen a case of bit-flip in a file stored in an USB flash drive. + + +@node Merging Files +@chapter Merging Files +@cindex merging files + +If you have several copies of a file but all of them are too damaged to +repair them (@pxref{Repairing Files}), lziprecover can try to produce a +correct file merging the good parts of the damaged copies. + +The merge may succeed even if some copies of the file have all the +headers and trailers damaged, as long as there is at least one copy of +every header and trailer intact, even if they are in different copies of +the file. + +The merge will fail if the damaged areas overlap (at least one byte is +damaged in all copies), or are adjacent and the boundary can't be +determined, or if the copies have too many damaged areas. + +To give you an idea of its possibilities, when merging two copies each +of them with one damaged area affecting 1 percent of the copy, the +probability of obtaining a correct file is about 98 percent. With three +such copies the probability rises to 99.97 percent. For large files with +small errors, the probability approaches 100 percent even with only two +copies. + + @node File Format @chapter File Format @cindex file format @@ -368,9 +409,8 @@ lziprecover -D 10000-15000 file.lz @sp 1 @noindent -Example 5: Repair a one-byte corruption in the single-member file -@samp{file.lz}. (Indented lines are abridged error messages from -lziprecover). +Example 5: Repair small errors in the file @samp{file.lz}. (Indented +lines are abridged diagnostic messages from lziprecover). @example lziprecover -v -R file.lz @@ -422,27 +462,12 @@ Example 8: Recover the first volume of those created with the command @w{@code{lzip -b 32MiB -S 650MB big_db}} from two copies, @samp{big_db1_00001.lz} and @samp{big_db2_00001.lz}, with member 07 damaged in the first copy, member 18 damaged in the second copy, and -member 12 damaged in both copies. Two correct copies are produced and -compared. +member 12 damaged in both copies. The correct file produced is saved in +@samp{big_db_00001.lz}. @example -lziprecover -s big_db1_00001.lz -lziprecover -s big_db2_00001.lz -lziprecover -t rec*big_db1_00001.lz - rec07big_db1_00001.lz: crc mismatch - rec12big_db1_00001.lz: crc mismatch -lziprecover -t rec*big_db2_00001.lz - rec12big_db2_00001.lz: crc mismatch - rec18big_db2_00001.lz: crc mismatch -lziprecover -m -v rec12big_db1_00001.lz rec12big_db2_00001.lz +lziprecover -m -v -o big_db_00001.lz big_db1_00001.lz big_db2_00001.lz Input files merged successfully -cp rec07big_db2_00001.lz rec07big_db1_00001.lz -cp rec12big_db1_00001_fixed.lz rec12big_db1_00001.lz -cp rec12big_db1_00001_fixed.lz rec12big_db2_00001.lz -cp rec18big_db1_00001.lz rec18big_db2_00001.lz -cat rec*big_db1_00001.lz > big_db3_00001.lz -cat rec*big_db2_00001.lz > big_db4_00001.lz -zcmp big_db3_00001.lz big_db4_00001.lz @end example diff --git a/file_index.cc b/file_index.cc index 41bee41..997003a 100644 --- a/file_index.cc +++ b/file_index.cc @@ -52,21 +52,32 @@ const char * format_num( unsigned long long num, } -File_index::File_index( const int infd ) : retval_( 0 ) +Block Block::split( const long long pos ) + { + if( pos_ < pos && end() > pos ) + { + const Block b( pos_, pos - pos_ ); + pos_ = pos; size_ -= b.size_; + return b; + } + return Block( 0, 0 ); + } + + +File_index::File_index( const int infd ) + : + isize( lseek( infd, 0, SEEK_END ) ), retval_( 0 ) { - const long long isize = lseek( infd, 0, SEEK_END ); if( isize < 0 ) { error_ = "Input file is not seekable :"; error_ += std::strerror( errno ); retval_ = 1; return; } + if( isize < min_member_size ) + { error_ = "Input file is too short."; retval_ = 2; return; } if( isize > INT64_MAX ) { error_ = "Input file is too long (2^63 bytes or more)."; retval_ = 2; return; } - long long pos = isize; // always points to a header or EOF - File_header header; - File_trailer trailer; - if( isize < min_member_size ) - { error_ = "Input file is too short."; retval_ = 2; return; } + File_header header; if( seek_read( infd, header.data, File_header::size, 0 ) != File_header::size ) { error_ = "Error reading member header :"; error_ += std::strerror( errno ); retval_ = 1; return; } @@ -77,10 +88,12 @@ File_index::File_index( const int infd ) : retval_( 0 ) { error_ = "Version "; error_ += format_num( header.version() ); error_ += "member format not supported."; retval_ = 2; return; } + long long pos = isize; // always points to a header or to EOF while( pos >= min_member_size ) { - if( seek_read( infd, trailer.data, File_trailer::size(), - pos - File_trailer::size() ) != File_trailer::size() ) + File_trailer trailer; + if( seek_read( infd, trailer.data, File_trailer::size, + pos - File_trailer::size ) != File_trailer::size ) { error_ = "Error reading member trailer :"; error_ += std::strerror( errno ); retval_ = 1; break; } const long long member_size = trailer.member_size(); @@ -105,9 +118,9 @@ File_index::File_index( const int infd ) : retval_( 0 ) if( member_vector.size() == 0 && isize - pos > File_header::size && seek_read( infd, header.data, File_header::size, pos ) == File_header::size && header.verify_magic() && header.verify_version() ) - { // last trailer is corrupt - error_ = "Member size in trailer is corrupt at pos "; - error_ += format_num( isize - 8 ); retval_ = 2; break; + { + error_ = "Last member in input file is truncated or corrupt."; + retval_ = 2; break; } pos -= member_size; member_vector.push_back( Member( 0, trailer.data_size(), @@ -132,3 +145,102 @@ File_index::File_index( const int infd ) : retval_( 0 ) member_vector[i+1].dblock.pos( end ); } } + + +// All files in 'infd_vector' must be at least 'fsize' bytes long. +File_index::File_index( const std::vector< int > & infd_vector, + const long long fsize ) + : + isize( fsize ), retval_( 0 ) + { + if( isize < 0 ) + { error_ = "Input file is not seekable :"; + error_ += std::strerror( errno ); retval_ = 1; return; } + if( isize < min_member_size ) + { error_ = "Input file is too short."; retval_ = 2; return; } + if( isize > INT64_MAX ) + { error_ = "Input file is too long (2^63 bytes or more)."; + retval_ = 2; return; } + + const int files = infd_vector.size(); + File_header header; + bool done = false; + for( int i = 0; i < files && !done; ++i ) + { + const int infd = infd_vector[i]; + if( seek_read( infd, header.data, File_header::size, 0 ) != File_header::size ) + { error_ = "Error reading member header :"; + error_ += std::strerror( errno ); retval_ = 1; return; } + if( header.verify_magic() && header.verify_version() ) done = true; + } + if( !done ) + { error_ = "Bad magic number (file not in lzip format)."; + retval_ = 2; return; } + + long long pos = isize; // always points to a header or to EOF + while( pos >= min_member_size ) + { + long long member_size; + File_trailer trailer; + done = false; + for( int it = 0; it < files && !done; ++it ) + { + const int tfd = infd_vector[it]; + if( seek_read( tfd, trailer.data, File_trailer::size, + pos - File_trailer::size ) != File_trailer::size ) + { error_ = "Error reading member trailer :"; + error_ += std::strerror( errno ); retval_ = 1; goto error; } + member_size = trailer.member_size(); + if( member_size >= min_member_size && member_size <= pos ) + for( int ih = 0; ih < files && !done; ++ih ) + { + const int hfd = infd_vector[ih]; + if( seek_read( hfd, header.data, File_header::size, + pos - member_size ) != File_header::size ) + { error_ = "Error reading member header :"; + error_ += std::strerror( errno ); retval_ = 1; goto error; } + if( header.verify_magic() && header.verify_version() ) done = true; + } + } + if( !done ) + { + if( member_vector.size() == 0 ) // maybe trailing garbage + { --pos; continue; } + error_ = "Member size in trailer may be corrupt at pos "; + error_ += format_num( pos - 8 ); retval_ = 2; break; + } + if( member_vector.size() == 0 && isize - pos > File_header::size ) + for( int i = 0; i < files; ++i ) + { + const int infd = infd_vector[i]; + if( seek_read( infd, header.data, File_header::size, pos ) == File_header::size && + header.verify_magic() && header.verify_version() ) + { + error_ = "Last member in input file is truncated or corrupt."; + retval_ = 2; goto error; + } + } + pos -= member_size; + member_vector.push_back( Member( 0, trailer.data_size(), + pos, member_size ) ); + } +error: + if( pos != 0 || member_vector.size() == 0 ) + { + member_vector.clear(); + if( retval_ == 0 ) { error_ = "Can't create file index."; retval_ = 2; } + return; + } + std::reverse( member_vector.begin(), member_vector.end() ); + for( unsigned i = 0; i < member_vector.size() - 1; ++i ) + { + const long long end = member_vector[i].dblock.end(); + if( end < 0 || end > INT64_MAX ) + { + member_vector.clear(); + error_ = "Data in input file is too long (2^63 bytes or more)."; + retval_ = 2; return; + } + member_vector[i+1].dblock.pos( end ); + } + } diff --git a/file_index.h b/file_index.h index 2f055b1..92cf11c 100644 --- a/file_index.h +++ b/file_index.h @@ -25,7 +25,8 @@ class Block long long pos_, size_; // pos + size <= INT64_MAX public: - Block( const long long p, const long long s ) : pos_( p ), size_( s ) {} + Block( const long long p, const long long s ) + : pos_( p ), size_( s ) {} long long pos() const { return pos_; } long long size() const { return size_; } @@ -34,9 +35,17 @@ public: void pos( const long long p ) { pos_ = p; } void size( const long long s ) { size_ = s; } + bool operator==( const Block & b ) const + { return pos_ == b.pos_ && size_ == b.size_; } + bool operator!=( const Block & b ) const + { return pos_ != b.pos_ || size_ != b.size_; } + + bool operator<( const Block & b ) const { return pos_ < b.pos_; } + bool overlaps( const Block & b ) const { return ( pos_ < b.end() && b.pos_ < end() ); } void shift( Block & b ) { ++size_; ++b.pos_; --b.size_; } + Block split( const long long pos ); }; @@ -49,18 +58,35 @@ class File_index Member( const long long dp, const long long ds, const long long mp, const long long ms ) : dblock( dp, ds ), mblock( mp, ms ) {} + + bool operator==( const Member & m ) const { return ( mblock == m.mblock ); } + bool operator!=( const Member & m ) const { return ( mblock != m.mblock ); } }; std::vector< Member > member_vector; std::string error_; + long long isize; int retval_; public: - File_index( const int infd ); + File_index() : error_( "No index." ), isize( 0 ), retval_( 2 ) {} + explicit File_index( const int infd ); + File_index( const std::vector< int > & infd_vector, const long long fsize ); + int members() const { return member_vector.size(); } const std::string & error() const { return error_; } int retval() const { return retval_; } + bool operator==( const File_index & fi ) const + { + if( retval_ || fi.retval_ || isize != fi.isize || + member_vector.size() != fi.member_vector.size() ) return false; + for( unsigned i = 0; i < member_vector.size(); ++i ) + if( member_vector[i] != fi.member_vector[i] ) return false; + return true; + } + bool operator!=( const File_index & fi ) const { return !( *this == fi ); } + long long data_end() const { if( member_vector.size() ) return member_vector.back().dblock.end(); else return 0; } @@ -69,11 +95,14 @@ public: { if( member_vector.size() ) return member_vector.back().mblock.end(); else return 0; } + // total size including trailing garbage (if any) + long long file_size() const + { if( isize >= 0 ) return isize; else return 0; } + const Block & dblock( const int i ) const { return member_vector[i].dblock; } const Block & mblock( const int i ) const { return member_vector[i].mblock; } - int members() const { return (int)member_vector.size(); } }; diff --git a/lzip.h b/lzip.h index fcad09e..ea02a5f 100644 --- a/lzip.h +++ b/lzip.h @@ -195,7 +195,7 @@ struct File_header { return ( std::memcmp( data, magic_string, 4 ) == 0 ); } uint8_t version() const { return data[4]; } - bool verify_version() const { return ( data[4] <= 1 ); } + bool verify_version() const { return ( data[4] == 1 ); } unsigned dictionary_size() const { @@ -231,8 +231,7 @@ struct File_trailer // 4-11 size of the uncompressed data // 12-19 member size including header and trailer - static int size( const int version = 1 ) - { return ( ( version >= 1 ) ? 20 : 12 ); } + enum { size = 20 }; unsigned data_crc() const { @@ -301,16 +300,15 @@ void cleanup_and_fail( const std::string & output_filename, const int outfd, const int retval ); bool copy_file( const int infd, const int outfd, const long long max_size = -1 ); -bool try_decompress( const int fd, const unsigned long long file_size, - long long * failure_posp = 0 ); +bool try_decompress_member( const int fd, const unsigned long long msize, + long long * failure_posp = 0 ); bool verify_header( const File_header & header, const int verbosity ); -bool verify_single_member( const int fd, const long long file_size, - const int verbosity ); int merge_files( const std::vector< std::string > & filenames, const std::string & output_filename, const int verbosity, const bool force ); // defined in range_dec.cc +bool safe_seek( const int fd, const long long pos ); int list_files( const std::vector< std::string > & filenames, const int verbosity ); int range_decompress( const std::string & input_filename, diff --git a/main.cc b/main.cc index b3e6474..21a5b04 100644 --- a/main.cc +++ b/main.cc @@ -113,7 +113,6 @@ void show_help() " -R, --repair try to repair a small error in file\n" " -s, --split split multi-member file in single-member files\n" " -t, --test test compressed file integrity\n" -// " -u, --update convert file from version 0 to version 1\n" " -v, --verbose be verbose (a 2nd -v gives more)\n" "Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n" "Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n" diff --git a/merge.cc b/merge.cc index c254a59..c216870 100644 --- a/merge.cc +++ b/merge.cc @@ -35,70 +35,107 @@ namespace { -bool copy_and_diff_file( const std::vector< int > & infd_vector, - const int outfd, std::vector< Block > & block_vector ) +// Add 'bv' to 'block_vector' splitting blocks as needed to keep all the +// edges (pos and end of every block). +// 'block_vector' contains the result. 'bv' is destroyed. +void combine( std::vector< Block > & block_vector, std::vector< Block > & bv ) { - const int buffer_size = 65536; - std::vector< uint8_t * > buffer_vector( infd_vector.size() ); - for( unsigned i = 0; i < infd_vector.size(); ++i ) - buffer_vector[i] = new uint8_t[buffer_size]; - Block b( 0, 0 ); - long long partial_pos = 0; - int equal_bytes = 0; - bool error = false; - - while( true ) + if( block_vector.empty() ) { block_vector.swap( bv ); return; } + unsigned i1 = 0, i2 = 0; + while( i1 < block_vector.size() && i2 < bv.size() ) { - const int rd = readblock( infd_vector[0], buffer_vector[0], buffer_size ); - if( rd != buffer_size && errno ) - { show_error( "Error reading input file", errno ); error = true; break; } - if( rd > 0 ) + Block & b1 = block_vector[i1]; + Block & b2 = bv[i2]; + if( b1.overlaps( b2 ) ) { - for( unsigned i = 1; i < infd_vector.size(); ++i ) - if( readblock( infd_vector[i], buffer_vector[i], rd ) != rd ) - { show_error( "Error reading input file", errno ); - error = true; break; } - if( error ) break; - const int wr = writeblock( outfd, buffer_vector[0], rd ); - if( wr != rd ) - { show_error( "Error writing output file", errno ); - error = true; break; } - for( int i = 0; i < rd; ++i ) + if( b1 < b2 ) { - while( i < rd && b.pos() == 0 ) - { - for( unsigned j = 1; j < infd_vector.size(); ++j ) - if( buffer_vector[0][i] != buffer_vector[j][i] ) - { b.pos( partial_pos + i ); break; } // begin block - ++i; - } - while( i < rd && b.pos() > 0 ) - { - ++equal_bytes; - for( unsigned j = 1; j < infd_vector.size(); ++j ) - if( buffer_vector[0][i] != buffer_vector[j][i] ) - { equal_bytes = 0; break; } - if( equal_bytes >= 2 ) // end block - { - b.size( partial_pos + i - ( equal_bytes - 1 ) - b.pos() ); - block_vector.push_back( b ); - b.pos( 0 ); - equal_bytes = 0; - } - ++i; - } + Block b = b1.split( b2.pos() ); + block_vector.insert( block_vector.begin() + i1, b ); ++i1; } - partial_pos += rd; + else if( b2 < b1 ) + { + Block b( b2.pos(), b1.pos() - b2.pos() ); + b2.split( b1.pos() ); + block_vector.insert( block_vector.begin() + i1, b ); ++i1; + } + else if( b1.end() < b2.end() ) { b2.split( b1.end() ); ++i1; } + else if( b2.end() < b1.end() ) + { + Block b = b1.split( b2.end() ); + block_vector.insert( block_vector.begin() + i1, b ); ++i1; ++i2; + } + else { ++i1; ++i2; } // blocks are identical } - if( rd < buffer_size ) break; // EOF + else if( b1 < b2 ) ++i1; + else { block_vector.insert( block_vector.begin() + i1, b2 ); ++i1; ++i2; } } - if( b.pos() > 0 ) // finish last block + if( i2 < bv.size() ) // tail copy + block_vector.insert( block_vector.end(), bv.begin() + i2, bv.end() ); + } + + +bool diff_member( const long long mpos, const long long msize, + const std::vector< int > & infd_vector, + std::vector< Block > & block_vector ) + { + const int files = infd_vector.size(); + const int buffer_size = 65536; + uint8_t * const buffer1 = new uint8_t[buffer_size]; + uint8_t * const buffer2 = new uint8_t[buffer_size]; + + bool error = false; + for( int i1 = 0; i1 + 1 < files && !error; ++i1 ) { - b.size( partial_pos - b.pos() ); - block_vector.push_back( b ); + for( int i2 = i1 + 1; i2 < files && !error; ++i2 ) + { + std::vector< Block > bv; + long long partial_pos = 0; + const int fd1 = infd_vector[i1], fd2 = infd_vector[i2]; + int begin = -1; // begin of block. -1 means no block + bool prev_equal = true; + if( !safe_seek( fd1, mpos ) || !safe_seek( fd2, mpos ) ) + { error = true; break; } + + while( msize > partial_pos ) + { + const int size = std::min( (long long)buffer_size, msize - partial_pos ); + const int rd = readblock( fd1, buffer1, size ); + if( rd != size && errno ) + { show_error( "Error reading input file", errno ); error = true; break; } + if( rd > 0 ) + { + if( readblock( fd2, buffer2, rd ) != rd ) + { show_error( "Error reading input file", errno ); + error = true; break; } + for( int i = 0; i < rd; ++i ) + { + if( buffer1[i] != buffer2[i] ) + { + prev_equal = false; + if( begin < 0 ) begin = partial_pos + i; // begin block + } + else if( !prev_equal ) prev_equal = true; + else if( begin >= 0 ) // end block + { + Block b( mpos + begin, partial_pos + i - 1 - begin ); + begin = -1; + bv.push_back( b ); + } + } + partial_pos += rd; + } + if( rd < buffer_size ) break; // EOF + } + if( begin >= 0 ) // finish last block + { + Block b( mpos + begin, partial_pos - prev_equal - begin ); + bv.push_back( b ); + } + combine( block_vector, bv ); + } } - for( unsigned i = 0; i < infd_vector.size(); ++i ) - delete[] buffer_vector[i]; + delete[] buffer2; delete[] buffer1; return !error; } @@ -116,15 +153,16 @@ int ipow( const unsigned base, const unsigned exponent ) int open_input_files( const std::vector< std::string > & filenames, - std::vector< int > & infd_vector, long long & isize, - const int verbosity ) + std::vector< int > & infd_vector, + File_index & file_index, const int verbosity ) { + const int files = filenames.size(); bool identical = false; - for( unsigned i = 1; i < filenames.size(); ++i ) + for( int i = 1; i < files; ++i ) if( filenames[0] == filenames[i] ) { identical = true; break; } if( !identical ) - for( unsigned i = 0; i < filenames.size(); ++i ) + for( int i = 0; i < files; ++i ) { struct stat in_stats; ino_t st_ino0 = 0; @@ -137,15 +175,27 @@ int open_input_files( const std::vector< std::string > & filenames, } if( identical ) { show_error( "Two input files are the same." ); return 2; } - isize = 0; - for( unsigned i = 0; i < filenames.size(); ++i ) + long long isize = 0; + for( int i = 0; i < files; ++i ) { - const long long tmp = lseek( infd_vector[i], 0, SEEK_END ); - if( tmp < 0 ) + long long tmp; + const File_index fi( infd_vector[i] ); + if( fi.retval() == 0 ) // file format is intact { - if( verbosity >= 0 ) - std::fprintf( stderr, "File '%s' is not seekable.\n", filenames[i].c_str() ); - return 1; + if( file_index.retval() != 0 ) file_index = fi; + else if( file_index != fi ) + { show_error( "Input files are different." ); return 2; } + tmp = file_index.file_size(); + } + else // file format is damaged + { + tmp = lseek( infd_vector[i], 0, SEEK_END ); + if( tmp < 0 ) + { + if( verbosity >= 0 ) + std::fprintf( stderr, "File '%s' is not seekable.\n", filenames[i].c_str() ); + return 1; + } } if( i == 0 ) { @@ -157,23 +207,33 @@ int open_input_files( const std::vector< std::string > & filenames, { show_error( "Sizes of input files are different." ); return 2; } } - for( unsigned i = 0; i < filenames.size(); ++i ) - if( !verify_single_member( infd_vector[i], isize, verbosity ) ) - return 2; - - for( unsigned i = 0; i < filenames.size(); ++i ) + if( file_index.retval() != 0 ) { - if( lseek( infd_vector[i], 0, SEEK_SET ) < 0 ) - { show_error( "Seek error in input file", errno ); return 1; } - if( try_decompress( infd_vector[i], isize ) ) + const File_index fi( infd_vector, isize ); + if( fi.retval() == 0 ) // file format could be recovered + file_index = fi; + else + { show_error( "Format damaged in all input files." ); return 2; } + } + + for( int i = 0; i < files; ++i ) + { + const int infd = infd_vector[i]; + bool error = false; + for( int j = 0; j < file_index.members(); ++j ) + { + const long long mpos = file_index.mblock( j ).pos(); + const long long msize = file_index.mblock( j ).size(); + if( !safe_seek( infd, mpos ) ) return 1; + if( !try_decompress_member( infd, msize ) ) { error = true; break; } + } + if( !error ) { if( verbosity >= 1 ) std::printf( "File '%s' has no errors. Recovery is not needed.\n", filenames[i].c_str() ); return 0; } - if( lseek( infd_vector[i], 0, SEEK_SET ) < 0 ) - { show_error( "Seek error in input file", errno ); return 1; } } return -1; } @@ -221,16 +281,15 @@ bool copy_file( const int infd, const int outfd, const long long max_size ) } -bool try_decompress( const int fd, const unsigned long long file_size, - long long * failure_posp ) +bool try_decompress_member( const int fd, const unsigned long long msize, + long long * failure_posp ) { try { Range_decoder rdec( fd ); File_header header; rdec.read_data( header.data, File_header::size ); if( !rdec.finished() && // End Of File - header.verify_magic() && - header.version() == 1 && + header.verify_magic() && header.verify_version() && header.dictionary_size() >= min_dictionary_size && header.dictionary_size() <= max_dictionary_size ) { @@ -238,7 +297,7 @@ bool try_decompress( const int fd, const unsigned long long file_size, Pretty_print dummy( "", -1 ); if( decoder.decode_member( dummy ) == 0 && - rdec.member_position() == file_size ) return true; + rdec.member_position() == msize ) return true; if( failure_posp ) *failure_posp = rdec.member_position(); } } @@ -259,12 +318,7 @@ bool verify_header( const File_header & header, const int verbosity ) show_error( "Bad magic number (file not in lzip format)." ); return false; } - if( header.version() == 0 ) - { - show_error( "Version 0 member format can't be recovered." ); - return false; - } - if( header.version() != 1 ) + if( !header.verify_version() ) { if( verbosity >= 0 ) std::fprintf( stderr, "Version %d member format not supported.\n", @@ -275,116 +329,106 @@ bool verify_header( const File_header & header, const int verbosity ) } -bool verify_single_member( const int fd, const long long file_size, - const int verbosity ) - { - File_header header; - if( lseek( fd, 0, SEEK_SET ) < 0 || - readblock( fd, header.data, File_header::size ) != File_header::size ) - { show_error( "Error reading member header", errno ); return false; } - if( !verify_header( header, verbosity ) ) return false; - - File_trailer trailer; - if( lseek( fd, -File_trailer::size(), SEEK_END ) < 0 || - readblock( fd, trailer.data, File_trailer::size() ) != File_trailer::size() ) - { show_error( "Error reading member trailer", errno ); return false; } - const long long member_size = trailer.member_size(); - if( member_size != file_size ) - { - if( member_size < file_size && - lseek( fd, -member_size, SEEK_END ) > 0 && - readblock( fd, header.data, File_header::size ) == File_header::size && - verify_header( header, verbosity ) ) - show_error( "Input file has more than 1 member. Split it first." ); - else - show_error( "Member size in input file trailer is corrupt." ); - return false; - } - return true; - } - - int merge_files( const std::vector< std::string > & filenames, const std::string & output_filename, const int verbosity, const bool force ) { - std::vector< int > infd_vector( filenames.size() ); - long long isize = 0; - const int retval = open_input_files( filenames, infd_vector, isize, verbosity ); + const int files = filenames.size(); + std::vector< int > infd_vector( files ); + File_index file_index; + const int retval = + open_input_files( filenames, infd_vector, file_index, verbosity ); if( retval >= 0 ) return retval; + if( !safe_seek( infd_vector[0], 0 ) ) return 1; const int outfd = open_outstream_rw( output_filename, force ); if( outfd < 0 ) return 1; - - // vector of data blocks differing among the copies of the input file. - std::vector< Block > block_vector; - if( !copy_and_diff_file( infd_vector, outfd, block_vector ) ) + if( !copy_file( infd_vector[0], outfd ) ) // copy whole file cleanup_and_fail( output_filename, outfd, 1 ); - if( block_vector.size() == 0 ) - { show_error( "Input files are identical. Recovery is not possible." ); - cleanup_and_fail( output_filename, outfd, 2 ); } - - const bool single_block = ( block_vector.size() == 1 ); - if( single_block && block_vector[0].size() < 2 ) - { show_error( "Input files have the same byte damaged." - " Try repairing one of them." ); - cleanup_and_fail( output_filename, outfd, 2 ); } - - if( ipow( filenames.size(), block_vector.size() ) >= INT_MAX || - ( single_block && - ipow( filenames.size(), 2 ) >= INT_MAX / block_vector[0].size() ) ) - { show_error( "Input files are too damaged. Recovery is not possible." ); - cleanup_and_fail( output_filename, outfd, 2 ); } - - const int shifts = ( single_block ? block_vector[0].size() - 1 : 1 ); - if( single_block ) + for( int j = 0; j < file_index.members(); ++j ) { - Block b( block_vector[0].pos() + 1, block_vector[0].size() - 1 ); - block_vector[0].size( 1 ); - block_vector.push_back( b ); - } + const long long mpos = file_index.mblock( j ).pos(); + const long long msize = file_index.mblock( j ).size(); + // vector of data blocks differing among the copies of the current member + std::vector< Block > block_vector; + if( !diff_member( mpos, msize, infd_vector, block_vector ) || + !safe_seek( outfd, mpos ) ) + cleanup_and_fail( output_filename, outfd, 1 ); - const int base_variations = ipow( filenames.size(), block_vector.size() ); - const int variations = ( base_variations * shifts ) - 2; - bool done = false; - for( int var = 1; var <= variations; ++var ) - { - if( verbosity >= 1 ) + if( block_vector.size() == 0 ) { - std::printf( "Trying variation %d of %d \r", var, variations ); + if( file_index.members() > 1 && try_decompress_member( outfd, msize ) ) + continue; + show_error( "Input files are (partially) identical. Recovery is not possible." ); + cleanup_and_fail( output_filename, outfd, 2 ); + } + + const int size0 = block_vector[0].size(); + const bool single_block = ( block_vector.size() == 1 ); + if( ipow( files, block_vector.size() ) >= INT_MAX || + ( single_block && ipow( files, 2 ) >= INT_MAX / size0 ) ) + { show_error( "Input files are too damaged. Recovery is not possible." ); + cleanup_and_fail( output_filename, outfd, 2 ); } + + const int shifts = ( single_block && size0 > 1 ) ? size0 - 1 : 1; + if( single_block && size0 > 1 ) + { + Block b( block_vector[0].pos() + 1, size0 - 1 ); + block_vector[0].size( 1 ); + block_vector.push_back( b ); + } + + if( verbosity >= 1 && file_index.members() > 1 ) + { + std::printf( "Merging member %d\n", j + 1 ); std::fflush( stdout ); } - int tmp = var; - for( unsigned i = 0; i < block_vector.size(); ++i ) + const int base_variations = ipow( files, block_vector.size() ); + const int variations = base_variations * shifts; + bool done = false; + for( int var = 0; var < variations; ++var ) { - const int infd = infd_vector[tmp % filenames.size()]; - tmp /= filenames.size(); - if( lseek( infd, block_vector[i].pos(), SEEK_SET ) < 0 || - lseek( outfd, block_vector[i].pos(), SEEK_SET ) < 0 || - !copy_file( infd, outfd, block_vector[i].size() ) ) - { show_error( "Error reading output file", errno ); - cleanup_and_fail( output_filename, outfd, 1 ); } + if( verbosity >= 1 ) + { + std::printf( "Trying variation %d of %d \r", var + 1, variations ); + std::fflush( stdout ); + } + int tmp = var; + for( unsigned i = 0; i < block_vector.size(); ++i ) + { + const int infd = infd_vector[tmp % files]; + tmp /= files; + if( lseek( infd, block_vector[i].pos(), SEEK_SET ) < 0 || + lseek( outfd, block_vector[i].pos(), SEEK_SET ) < 0 || + !copy_file( infd, outfd, block_vector[i].size() ) ) + { show_error( "Error reading output file", errno ); + cleanup_and_fail( output_filename, outfd, 1 ); } + } + if( !safe_seek( outfd, mpos ) ) + cleanup_and_fail( output_filename, outfd, 1 ); + if( try_decompress_member( outfd, msize ) ) + { done = true; break; } + if( var > 0 && var % base_variations == 0 ) + block_vector[0].shift( block_vector[1] ); + } + if( verbosity >= 1 ) std::printf( "\n" ); + if( !done ) + { + if( verbosity >= 2 ) + for( unsigned i = 0; i < block_vector.size(); ++i ) + std::fprintf( stderr, "area %2d from offset %6lld to %6lld\n", i + 1, + block_vector[i].pos(), block_vector[i].end() - 1 ); + show_error( "Some error areas overlap. Can't recover input file." ); + cleanup_and_fail( output_filename, outfd, 2 ); } - if( lseek( outfd, 0, SEEK_SET ) < 0 ) - { show_error( "Seek error in output file", errno ); - cleanup_and_fail( output_filename, outfd, 1 ); } - if( try_decompress( outfd, isize ) ) - { done = true; break; } - if( var % base_variations == 0 ) block_vector[0].shift( block_vector[1] ); } - if( verbosity >= 1 ) std::printf( "\n" ); if( close( outfd ) != 0 ) { show_error( "Error closing output file", errno ); cleanup_and_fail( output_filename, -1, 1 ); } - if( !done ) - { - show_error( "Some error areas overlap. Can't recover input file." ); - cleanup_and_fail( output_filename, -1, 2 ); - } if( verbosity >= 1 ) std::printf( "Input files merged successfully.\n" ); return 0; diff --git a/range_dec.cc b/range_dec.cc index 59be01f..27ceba3 100644 --- a/range_dec.cc +++ b/range_dec.cc @@ -101,13 +101,6 @@ void parse_range( const char * const ptr, Block & range ) } -bool safe_seek( const int fd, const long long pos ) - { - if( lseek( fd, pos, SEEK_SET ) == pos ) return true; - show_error( "Seek error", errno ); return false; - } - - int decompress_member( const int infd, const int outfd, const Pretty_print & pp, const unsigned long long mpos, @@ -170,7 +163,7 @@ int list_file( const std::string & input_filename, const Pretty_print & pp ) const int infd = open_instream( input_filename, &in_stats, true, true ); if( infd < 0 ) return 1; - File_index file_index( infd ); + const File_index file_index( infd ); close( infd ); if( file_index.retval() != 0 ) { show_error( file_index.error().c_str() ); return file_index.retval(); } @@ -208,6 +201,13 @@ int list_file( const std::string & input_filename, const Pretty_print & pp ) } // end namespace +bool safe_seek( const int fd, const long long pos ) + { + if( lseek( fd, pos, SEEK_SET ) == pos ) return true; + show_error( "Seek error", errno ); return false; + } + + int list_files( const std::vector< std::string > & filenames, const int verbosity ) { @@ -234,7 +234,7 @@ int range_decompress( const std::string & input_filename, const int infd = open_instream( input_filename, &in_stats, true, true ); if( infd < 0 ) return 1; - File_index file_index( infd ); + const File_index file_index( infd ); if( file_index.retval() != 0 ) { show_error( file_index.error().c_str() ); return file_index.retval(); } @@ -259,6 +259,7 @@ int range_decompress( const std::string & input_filename, else { outfd = open_outstream_rw( output_filename, force ); if( outfd < 0 ) return 1; } + Pretty_print pp( input_filename, verbosity ); int retval = 0; for( int i = 0; i < file_index.members(); ++i ) diff --git a/repair.cc b/repair.cc index e9cef61..712002b 100644 --- a/repair.cc +++ b/repair.cc @@ -28,6 +28,7 @@ #include #include "lzip.h" +#include "file_index.h" int seek_read( const int fd, uint8_t * const buf, const int size, @@ -55,72 +56,84 @@ int repair_file( const std::string & input_filename, struct stat in_stats; const int infd = open_instream( input_filename, &in_stats, true, true ); if( infd < 0 ) return 1; - const long long isize = lseek( infd, 0, SEEK_END ); - if( isize < 0 ) - { show_error( "Input file is not seekable", errno ); return 1; } - if( isize < min_member_size ) - { show_error( "Input file is too short." ); return 2; } - if( !verify_single_member( infd, isize, verbosity ) ) return 2; - if( lseek( infd, 0, SEEK_SET ) < 0 ) - { show_error( "Seek error in input file", errno ); return 1; } - long long failure_pos = 0; - if( try_decompress( infd, isize, &failure_pos ) ) + const File_index file_index( infd ); + if( file_index.retval() != 0 ) + { show_error( file_index.error().c_str() ); return file_index.retval(); } + + int outfd = -1; + for( int i = 0; i < file_index.members(); ++i ) + { + const long long mpos = file_index.mblock( i ).pos(); + const long long msize = file_index.mblock( i ).size(); + if( !safe_seek( infd, mpos ) ) + cleanup_and_fail( output_filename, outfd, 1 ); + long long failure_pos = 0; + if( try_decompress_member( infd, msize, &failure_pos ) ) continue; + if( failure_pos >= msize - 8 ) failure_pos = msize - 8 - 1; + if( failure_pos < File_header::size ) + { show_error( "Can't repair error in input file." ); + cleanup_and_fail( output_filename, outfd, 2 ); } + + if( outfd < 0 ) // first damaged member found + { + if( !safe_seek( infd, 0 ) ) return 1; + outfd = open_outstream_rw( output_filename, force ); + if( outfd < 0 ) { close( infd ); return 1; } + if( !copy_file( infd, outfd ) ) // copy whole file + cleanup_and_fail( output_filename, outfd, 1 ); + } + + if( verbosity >= 1 ) + { + std::printf( "Repairing member %d\n", i + 1 ); + std::fflush( stdout ); + } + const long long min_pos = + std::max( (long long)File_header::size, failure_pos - 1000 ); + bool done = false; + for( long long pos = failure_pos; pos >= min_pos && !done ; --pos ) + { + if( verbosity >= 1 ) + { + std::printf( "Trying position %llu \r", mpos + pos ); + std::fflush( stdout ); + } + uint8_t byte; + if( seek_read( outfd, &byte, 1, mpos + pos ) != 1 ) + { show_error( "Error reading output file", errno ); + cleanup_and_fail( output_filename, outfd, 1 ); } + for( int i = 0; i < 256; ++i ) + { + ++byte; + if( seek_write( outfd, &byte, 1, mpos + pos ) != 1 || + lseek( outfd, mpos, SEEK_SET ) < 0 ) + { show_error( "Error writing output file", errno ); + cleanup_and_fail( output_filename, outfd, 1 ); } + if( i == 255 ) break; + if( try_decompress_member( outfd, msize ) ) + { done = true; break; } + } + } + if( verbosity >= 1 ) std::printf( "\n" ); + if( !done ) + { + show_error( "Error is larger than 1 byte. Can't repair input file." ); + cleanup_and_fail( output_filename, outfd, 2 ); + } + } + + if( outfd < 0 ) { if( verbosity >= 1 ) std::printf( "Input file has no errors. Recovery is not needed.\n" ); return 0; } - if( failure_pos >= isize - 8 ) failure_pos = isize - 8 - 1; - if( failure_pos < File_header::size ) - { show_error( "Can't repair error in input file." ); return 2; } - - if( lseek( infd, 0, SEEK_SET ) < 0 ) - { show_error( "Seek error in input file", errno ); return 1; } - - const int outfd = open_outstream_rw( output_filename, force ); - if( outfd < 0 ) { close( infd ); return 1; } - if( !copy_file( infd, outfd ) ) - cleanup_and_fail( output_filename, outfd, 1 ); - - const long long min_pos = - std::max( (long long)File_header::size, failure_pos - 1000 ); - bool done = false; - for( long long pos = failure_pos; pos >= min_pos && !done ; --pos ) - { - if( verbosity >= 1 ) - { - std::printf( "Trying position %llu \r", pos ); - std::fflush( stdout ); - } - uint8_t byte; - if( seek_read( outfd, &byte, 1, pos ) != 1 ) - { show_error( "Error reading output file", errno ); - cleanup_and_fail( output_filename, outfd, 1 ); } - for( int i = 0; i < 256; ++i ) - { - ++byte; - if( seek_write( outfd, &byte, 1, pos ) != 1 || - lseek( outfd, 0, SEEK_SET ) < 0 ) - { show_error( "Error writing output file", errno ); - cleanup_and_fail( output_filename, outfd, 1 ); } - if( i == 255 ) break; - if( try_decompress( outfd, isize ) ) - { done = true; break; } - } - } - if( verbosity >= 1 ) std::printf( "\n" ); - if( close( outfd ) != 0 ) { show_error( "Error closing output file", errno ); cleanup_and_fail( output_filename, -1, 1 ); } - if( !done ) - { - show_error( "Error is larger than 1 byte. Can't repair input file." ); - cleanup_and_fail( output_filename, -1, 2 ); - } if( verbosity >= 1 ) std::printf( "Copy of input file repaired successfully.\n" ); return 0; diff --git a/split.cc b/split.cc index ac7627d..bec8a26 100644 --- a/split.cc +++ b/split.cc @@ -90,7 +90,7 @@ int do_split_file( const std::string & input_filename, uint8_t * & base_buffer, const int verbosity, const bool force ) { const int hsize = File_header::size; - const int tsize = File_trailer::size(); + const int tsize = File_trailer::size; const int buffer_size = 65536; const int base_buffer_size = tsize + buffer_size + hsize; base_buffer = new uint8_t[base_buffer_size]; @@ -99,7 +99,8 @@ int do_split_file( const std::string & input_filename, uint8_t * & base_buffer, struct stat in_stats; const int infd = open_instream( input_filename, &in_stats, true, true ); if( infd < 0 ) return 1; - File_index file_index( infd ); + const File_index file_index( infd ); + if( file_index.retval() != 0 ) show_error( file_index.error().c_str() ); const int max_members = ( file_index.retval() ? 999999 : file_index.members() ); int max_digits = 1; for( int i = max_members; i >= 10; i /= 10 ) ++max_digits; diff --git a/testsuite/check.sh b/testsuite/check.sh index ea6e768..4ac7f59 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -23,10 +23,15 @@ mkdir tmp cd "${objdir}"/tmp in="${testdir}"/test.txt -in_lz="${testdir}"/test_v1.lz +in_lz="${testdir}"/test.txt.lz inD="${testdir}"/test921-1921.txt -fox5="${testdir}"/fox5_bad.txt -fox5_lz="${testdir}"/fox5_bad.lz +fox5_lz="${testdir}"/fox5.lz +f5b1="${testdir}"/fox5_bad1.txt +f5b1_lz="${testdir}"/fox5_bad1.lz +f5b2_lz="${testdir}"/fox5_bad2.lz +f5b3_lz="${testdir}"/fox5_bad3.lz +f5b4_lz="${testdir}"/fox5_bad4.lz +f5b5_lz="${testdir}"/fox5_bad5.lz bad1_lz="${testdir}"/test_bad1.lz bad2_lz="${testdir}"/test_bad2.lz bad3_lz="${testdir}"/test_bad3.lz @@ -35,91 +40,140 @@ bad5_lz="${testdir}"/test_bad5.lz fail=0 # Description of test files for lziprecover: -# fox5_bad.lz: byte at offset 188 changed from 0x34 to 0x33 +# fox5_bad1.lz: byte at offset 62 changed from 0x50 to 0x70 (CRC) +# byte at offset 144 changed from 0x2D to 0x2E (data_size) +# byte at offset 188 changed from 0x34 to 0x33 (mid stream) +# byte at offset 247 changed from 0x2A to 0x2B (first byte) +# byte at offset 378 changed from 0xA0 to 0x20 (EOS marker) +# fox5_bad2.lz: [ 30- 49] --> zeroed; +# fox5_bad3.lz: [100-299] --> zeroed; +# fox5_bad4.lz: [250-349] --> zeroed; +# fox5_bad5.lz: [300-399] --> zeroed; # test_bad1.lz: byte at offset 67 changed from 0xCC to 0x33 -# test_bad2.lz: [ 34- 66) --> copy of bytes [ 68- 100) -# test_bad3.lz: [ 512-1536) --> zeroed; [2560-3584) --> zeroed -# test_bad4.lz: [3072-4096) --> random data; [4608-5632) --> zeroed -# test_bad5.lz: [1024-2048) --> random data; [5120-6144) --> random data +# test_bad2.lz: [ 34- 65] --> copy of bytes [ 68- 99] +# test_bad3.lz: [ 512-1535] --> zeroed; [2560-3583] --> zeroed +# test_bad4.lz: [3072-4095] --> random data; [4608-5631] --> zeroed +# test_bad5.lz: [1024-2047] --> random data; [5120-6143] --> random data printf "testing lziprecover-%s..." "$2" "${LZIPRECOVER}" -lq -if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi +if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi "${LZIPRECOVER}" -mq "${bad1_lz}" -if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi +if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi "${LZIPRECOVER}" -Rq -if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi +if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi "${LZIPRECOVER}" -sq -if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi +if [ $? = 1 ] ; then printf . ; else fail=1 ; printf - ; fi -"${LZIP}" -t "${testdir}"/test_v0.lz || fail=1 -printf . -"${LZIP}" -cd "${testdir}"/test_v0.lz > copy || fail=1 -cmp "${in}" copy || fail=1 -printf . - -"${LZIP}" -t "${testdir}"/test_v1.lz || fail=1 -printf . -"${LZIP}" -cd "${testdir}"/test_v1.lz > copy || fail=1 +"${LZIP}" -t "${testdir}"/test.txt.lz || fail=1 +"${LZIP}" -cd "${testdir}"/test.txt.lz > copy || fail=1 cmp "${in}" copy || fail=1 printf . "${LZIPRECOVER}" -D 921-1921 -fo copy "${in_lz}" || fail=1 cmp "${inD}" copy || fail=1 -printf . "${LZIPRECOVER}" -D 921,1000 "${in_lz}" > copy || fail=1 cmp "${inD}" copy || fail=1 printf . -"${LZIPRECOVER}" -D0 -iq -fo copy "${fox5_lz}" -if [ $? = 2 ] && cmp "${fox5}" copy ; then printf . ; else fail=1 ; printf - ; fi -"${LZIPRECOVER}" -D0 -iq "${fox5_lz}" > copy -if [ $? = 2 ] && cmp "${fox5}" copy ; then printf . ; else fail=1 ; printf - ; fi +"${LZIPRECOVER}" -D0 -iq "${f5b1_lz}" -fo copy +if [ $? = 2 ] && cmp "${f5b1}" copy ; then printf . ; else fail=1 ; printf - ; fi +"${LZIPRECOVER}" -D0 -iq "${f5b1_lz}" > copy +if [ $? = 2 ] && cmp "${f5b1}" copy ; then printf . ; else fail=1 ; printf - ; fi +rm -f copy.lz +"${LZIPRECOVER}" -m -o copy.lz "${fox5_lz}" "${f5b1_lz}" +if [ $? = 0 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIPRECOVER}" -m -o copy.lz "${f5b1_lz}" "${fox5_lz}" +if [ $? = 0 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi "${LZIPRECOVER}" -m -o copy.lz "${bad1_lz}" "${bad2_lz}" "${bad1_lz}" -q -if [ $? != 2 ] ; then fail=1 ; printf - ; else printf . ; fi -"${LZIPRECOVER}" -m -o copy.lz "${bad1_lz}" "${bad2_lz}" || fail=1 -"${LZIPRECOVER}" -df copy.lz || fail=1 -cmp "${in}" copy || fail=1 +if [ $? = 2 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIPRECOVER}" -m -o copy.lz "${f5b1_lz}" "${f5b5_lz}" -q +if [ $? = 2 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIPRECOVER}" -m -o copy.lz "${f5b3_lz}" "${f5b5_lz}" -q +if [ $? = 2 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIPRECOVER}" -m -o copy.lz "${bad3_lz}" "${bad4_lz}" -q +if [ $? = 2 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi + +for i in "${f5b1_lz}" "${f5b3_lz}" "${f5b4_lz}" "${f5b5_lz}" ; do + "${LZIPRECOVER}" -mf -o copy.lz "${f5b2_lz}" "${i}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${i}" "${f5b2_lz}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + printf . +done + +for i in "${f5b3_lz}" "${f5b4_lz}" "${f5b5_lz}" ; do + "${LZIPRECOVER}" -mf -o copy.lz "${f5b1_lz}" "${f5b2_lz}" "${i}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${f5b1_lz}" "${i}" "${f5b2_lz}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${f5b2_lz}" "${f5b1_lz}" "${i}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${f5b2_lz}" "${i}" "${f5b1_lz}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${i}" "${f5b1_lz}" "${f5b2_lz}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${i}" "${f5b2_lz}" "${f5b1_lz}" || fail=1 + cmp "${fox5_lz}" copy.lz || fail=1 + printf . +done + +"${LZIPRECOVER}" -mf -o copy.lz "${f5b3_lz}" "${f5b4_lz}" "${f5b5_lz}" || fail=1 +cmp "${fox5_lz}" copy.lz || fail=1 +"${LZIPRECOVER}" -mf -o copy.lz "${f5b1_lz}" "${f5b3_lz}" "${f5b4_lz}" "${f5b5_lz}" || fail=1 +cmp "${fox5_lz}" copy.lz || fail=1 +"${LZIPRECOVER}" -mf -o copy.lz "${f5b2_lz}" "${f5b3_lz}" "${f5b4_lz}" "${f5b5_lz}" || fail=1 +cmp "${fox5_lz}" copy.lz || fail=1 +"${LZIPRECOVER}" -mf -o copy.lz "${f5b1_lz}" "${f5b2_lz}" "${f5b3_lz}" "${f5b4_lz}" "${f5b5_lz}" || fail=1 +cmp "${fox5_lz}" copy.lz || fail=1 printf . -"${LZIPRECOVER}" -m -o copy.lz "${bad2_lz}" "${bad1_lz}" || fail=1 -"${LZIPRECOVER}" -df copy.lz || fail=1 -cmp "${in}" copy || fail=1 + +"${LZIPRECOVER}" -mf -o copy.lz "${bad1_lz}" "${bad2_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 +"${LZIPRECOVER}" -mf -o copy.lz "${bad2_lz}" "${bad1_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 printf . for i in "${bad1_lz}" "${bad2_lz}" ; do for j in "${bad3_lz}" "${bad4_lz}" "${bad5_lz}" ; do - "${LZIPRECOVER}" -m -o copy.lz "${i}" "${j}" || fail=1 - "${LZIPRECOVER}" -df copy.lz || fail=1 - cmp "${in}" copy || fail=1 - printf . - "${LZIPRECOVER}" -m -o copy.lz "${j}" "${i}" || fail=1 - "${LZIPRECOVER}" -df copy.lz || fail=1 - cmp "${in}" copy || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${i}" "${j}" || fail=1 + cmp "${in_lz}" copy.lz || fail=1 + "${LZIPRECOVER}" -mf -o copy.lz "${j}" "${i}" || fail=1 + cmp "${in_lz}" copy.lz || fail=1 printf . done done -"${LZIPRECOVER}" -m -o copy.lz "${bad3_lz}" "${bad4_lz}" "${bad5_lz}" || fail=1 -"${LZIPRECOVER}" -df copy.lz || fail=1 -cmp "${in}" copy || fail=1 +"${LZIPRECOVER}" -mf -o copy.lz "${bad3_lz}" "${bad4_lz}" "${bad5_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 printf . -"${LZIPRECOVER}" -m -o copy.lz "${bad4_lz}" "${bad5_lz}" "${bad3_lz}" || fail=1 -"${LZIPRECOVER}" -df copy.lz || fail=1 -cmp "${in}" copy || fail=1 +"${LZIPRECOVER}" -mf -o copy.lz "${bad3_lz}" "${bad5_lz}" "${bad4_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 printf . -"${LZIPRECOVER}" -m -o copy.lz "${bad5_lz}" "${bad3_lz}" "${bad4_lz}" || fail=1 -"${LZIPRECOVER}" -df copy.lz || fail=1 -cmp "${in}" copy || fail=1 +"${LZIPRECOVER}" -mf -o copy.lz "${bad4_lz}" "${bad3_lz}" "${bad5_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 +printf . +"${LZIPRECOVER}" -mf -o copy.lz "${bad4_lz}" "${bad5_lz}" "${bad3_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 +printf . +"${LZIPRECOVER}" -mf -o copy.lz "${bad5_lz}" "${bad3_lz}" "${bad4_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 +printf . +"${LZIPRECOVER}" -mf -o copy.lz "${bad5_lz}" "${bad4_lz}" "${bad3_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 printf . -"${LZIPRECOVER}" -R "${in_lz}" || fail=1 -printf . +rm -f copy.lz +"${LZIPRECOVER}" -R -o copy.lz "${fox5_lz}" || fail=1 +if [ $? = 0 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi "${LZIPRECOVER}" -R -o copy.lz "${bad2_lz}" -q -if [ $? != 2 ] ; then fail=1 ; printf - ; else printf . ; fi -"${LZIPRECOVER}" -R -o copy.lz "${bad1_lz}" || fail=1 -"${LZIPRECOVER}" -df copy.lz || fail=1 -cmp "${in}" copy || fail=1 +if [ $? = 2 ] && [ ! -e copy.lz ] ; then printf . ; else fail=1 ; printf - ; fi +"${LZIPRECOVER}" -Rf -o copy.lz "${f5b1_lz}" || fail=1 +cmp "${fox5_lz}" copy.lz || fail=1 +printf . +"${LZIPRECOVER}" -Rf -o copy.lz "${bad1_lz}" || fail=1 +cmp "${in_lz}" copy.lz || fail=1 printf . cat "${in_lz}" "${in_lz}" "${in_lz}" > copy || framework_failure diff --git a/testsuite/fox5_bad.lz b/testsuite/fox5.lz similarity index 84% copy from testsuite/fox5_bad.lz copy to testsuite/fox5.lz index 8bfd3147e6ab29390ef836bc34bacef63b6b9996..3472f64f53189878a53ba897904b25ec994534e6 100644 GIT binary patch delta 12 UcmbQhJb`(_o{2IGCd!xq03O{0p#T5? delta 11 ScmbQhJb`(_9!BGdvX=oDY6K_% diff --git a/testsuite/fox5_bad1.lz b/testsuite/fox5_bad1.lz new file mode 100644 index 0000000000000000000000000000000000000000..a3b565867a09171678538a288d2ed72a40bbc0e9 GIT binary patch literal 400 zcmeZ?@(f_)VbGG|Sj4QF_R+iI=pxqtde3fNQjl6}^5c>03rDkGci1v_+dL64QRjTU zIqmVA>95u)|NqywfFbKl!E0Rx2nc}EJ`|Z3@LG=q^Nb0)F94VOw8`@?PV>kJKLud; HVVVa35Z{_F literal 0 HcmV?d00001 diff --git a/testsuite/fox5_bad.txt b/testsuite/fox5_bad1.txt similarity index 71% rename from testsuite/fox5_bad.txt rename to testsuite/fox5_bad1.txt index 813a71f..14e5367 100644 --- a/testsuite/fox5_bad.txt +++ b/testsuite/fox5_bad1.txt @@ -1,4 +1,4 @@ The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. -The quick brown fox c††zzzzzzzzzzzzzzzzzzzzzzThe quick brown fox jumps over the lazy dog. +The quick brown fox c††zzzzzzzzzzzzzzzzzzzzzzVhe quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. diff --git a/testsuite/fox5_bad.lz b/testsuite/fox5_bad2.lz similarity index 68% rename from testsuite/fox5_bad.lz rename to testsuite/fox5_bad2.lz index 8bfd3147e6ab29390ef836bc34bacef63b6b9996..9993ea7e3f387ab5c57c83701b3f6c0f02848b43 100644 GIT binary patch delta 33 YcmbQhJb`(FoCpIJF!9p9i60gK07*IqD*ylh delta 12 TcmbQhJb`&)z#c~9iMf{n8~Fsu diff --git a/testsuite/fox5_bad3.lz b/testsuite/fox5_bad3.lz new file mode 100644 index 0000000000000000000000000000000000000000..ef58e476b5bd4f6b8fe50e39e371d4fc1e003ac9 GIT binary patch literal 400 zcmeZ?@(f_)VbGG|Sj4QF_R+iI=pxqtde3fNQjl6}^5c>03rDkGci1v_+dL64QRjTU pIqmVA>95u)|NqywfFbKlz-wIw2nc}EK3L3yN)366SpQNIegJ7aMyUV* literal 0 HcmV?d00001 diff --git a/testsuite/fox5_bad4.lz b/testsuite/fox5_bad4.lz new file mode 100644 index 0000000000000000000000000000000000000000..0474bb919ecbfb0dc7cb45ad0c8a48f5a5357ef7 GIT binary patch literal 400 zcmeZ?@(f_)VbGG|Sj4QF_R+iI=pxqtde3fNQjl6}^5c>03rDkGci1v_+dL64QRjTU nIqmVA>95u)|NqywfFbKlz-wIw2nc}EK10SlsDo)rksf{kB*bxq literal 0 HcmV?d00001 diff --git a/testsuite/fox5_bad5.lz b/testsuite/fox5_bad5.lz new file mode 100644 index 0000000000000000000000000000000000000000..6ec274089d423cb429a2c5d776a2ae34cc2abccf GIT binary patch literal 400 zcmeZ?@(f_)VbGG|Sj4QF_R+iI=pxqtde3fNQjl6}^5c>03rDkGci1v_+dL64QRjTU lIqmVA>95u)|NqywfFbKlz-wIw2nc}EKEv2Ns26EU0RWKcc((um literal 0 HcmV?d00001 diff --git a/testsuite/test.txt.lz b/testsuite/test.txt.lz new file mode 100644 index 0000000000000000000000000000000000000000..4db881aa68489345e86b677d05091a773f26bbb5 GIT binary patch literal 11518 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 literal 0 HcmV?d00001 diff --git a/testsuite/test_bad1.lz b/testsuite/test_bad1.lz index 0b84883f91edbcfb9e983e45c8d083d9f5b06a52..687c8a141969cf9d7efc8dcfcbd341ddf61d165e 100644 GIT binary patch delta 11365 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 delta 11395 zcmV-}EPT`cS)5vs_G(TBpKkH5Ll^a#4d%YV4>m|C{L(P8%I z+N}3J%^dRqE`RC<(4-?v++;aTTl1o$HmuwZAh|-ytEK!dEcG)68kKQJWc75<1PHVX zCW1?8H)b)71wgp0c<=+#`#e=LFC3oPX*{EnF0nWSIrI^soiUk?i>p@JXLY-ZUypqB zd#Y{;Qh;VVFoU=#SkA+@wKwAVF;z}l)*9SNVp+oU9)Gf}^VS?Q7qF1)4k1l#=4d1^ zrgD+~)Z+iw*dAnNOaAK&wzaJK?O9cibK-mU$#_s#*=4arK?wFdia5lD(}=#y&s(MX zJ>StQrXMgZ^zOwQjo5nWHT*LXzAGuf_pLiS!Cef@r9q5doAzAYvZ7YRZ%{?@O}F%A zTBtZaU4Oky@+uW9*ULg+@W6eXuy-%6ADu}va8I<*s^KLFb<4Q1d6FMdNNtsuk`oEx zakeB&Nm>~Y0aqC6xf(EjHJrr=Xwr{2+H<^z8q73;ltP$Fzvl=#9$bG{ss4WKo##2x!VpF?F zUDHcSKuf#ASe_bM7A-llx5qAK^CUBK-gpQuw&C*Hv{B1mz$Iq=aIa3WzsH0b_zJ4> z6@O&fx`r+Ft5ne@VW7KoK>Gdn6hsbG!`%B!Iqm|w^Z2;<-9h}w~lGsVL0J;OiGSV z*hxvzX3y(|ug07H<6`Dm(kG<0kAEMHOCys3v!mOclZKM`pAD@!ggZYP6~5&|JuAX4a4Kq%=(;Vl>M{tZj)O0Efw0HjF^>!PXWA_T zvUm1vA=y7nDNITSU&1QNlYVrWE_Ox&$~%vhu!u$v#1UGs-XBrwY^zm#xPPc~3g!9q z31!_gsXpajDO)ej#J)C82APU>CIva)hJULGuo58VDb-*Azy{iK${x` z$=#9LpJG72@9b~3kz>2ZHhRX5mAxt;1(*0;fB63_RfFE%x-W$B`hGj8wxl{vzXjdn zWNr2F?}svPwz649^+3ZdJMVhQNqYe4UR`z0deT~CepeD6h)S;-1b<~Aymef%eiEhG zHN!im;DZkaLt1l5|DS^0n0~~>D^#NKsQD+n>FPUHlwAyn$(lu~#Cpy^xcT0x%I>5a z<%g_Mt;p?i*k!HtVU#dFXjGXq_Dtl6?Kb{He2>Zm<=*Dka~C(`as^q*V={OcY)#Hj zNx5ZwwKZZj0qedXLx0PN4jVx_%*GgFeH%gI0=XnY?{~Y!rMzA)VTXN0P@Q;aA%2Kz z{zbHlOULJ2!(B+4>y?MXFltbEKn_wLfY{k4uTuD(qC9^67DNZPM@o0R{!Nd`^|2kd z!G(*wKIVgx|0urk=#}P$e^GC~d*(#GfM~rEoNC(Z$z+whjDK-8o^DJevDefebV2@W zR^7^(r>ClcLGmhK_f&&J9ZSdjTqIZJxpKUSlo?@yq4Y~GmN&u`2j9UQgM^t16%T1l zB>*tZ(&g<-wjyPExbKr;&o(jlee5sgPc>}kX>jIQxWJ>Eg(elJ+dxhl$DdNoyD{)A zr9-gJfh)~_`hR3)M()oA)8FIASylt@Vm8unev8fzY+(#i)Rh{$JdH$03dzZ=+%MJn zRnF@|NqO8c7MCd0HYAM5bzU#1TcvXVVD`}Xf*tUjNZ3xnf5r8x;Ew1=@jWZX=g4!V|KV^|~3V*6S zjz?o>f`5S@U++&+-gD_4k< zUm$+{{n5|imPL_O3Xa_UTK#eT=IY)rUGmDET5s1L2{!awVEV(*3=}w+p^AC!L<=W> zqyDtuZE`>SEfR!&#_=k&u^Qlv)&RyR(V3Ao#aHRoJ-230mRVUX zL4Ux7R8=Z%wg0L)1MNC6^(#)uay?CkzR}&s&QGX*jwpjU*MK@QUBD@X_+|Jr;XC5$ znHth(LSnyMF#>!`exV)BU+C41&_qyQ45VZq8_Gqvu0wtk9Idt!-AM=fc^)%PR0!RP z5JOEud4&~N5af=$e#j>vvBVjVk5J>vyMHST+P4m7H0`!0kQ#D6L16h|EjWV?e4hQ1 z`y()72DdZmy6E7*11_2dffdYRbDyY~0}WF;+1lsn0W8mjn;u@B8aui(_uXDOu=Q~R z0&c8=IB#eD%pe#$p_`XY;eV;A zOCgCrZ=6>0-3eVxtjKy^Ko?Lcc(Z6#p8to-U>j!#Mz|jZwUQx%mMic3(YgbUC z>s$Y@Vx_hf3=N-S1n)_?1SWgN9WZnr`|oFO!rH2|-Q(h=2FMH(b;^UXBA z9fjPTVm|CJ2)`1JN>vg}z4zwqDuwJfd3w5e^o%$0ZWG={WoRg?jd~7`@P|X@*SmDb zIb_~YDTor6Mt|Z(Et{? zd_@;Dd9D4tVsE!(aI4i>EHk)YM*k=3)XFaGDdRadt4;3BWDV*mwo+*QNbhGTV>(rg+b_@-+vC_%dFht)G|;@ zz$z^dJBl-g6ZaW_B`1cAnAD67*BhJatHKPEV00ZGs%`Qz=-^G^itCbBbm}6iJox%g=fwB6VgmM3YIBo|(KfUUD_`o%&w8 z(PX;gxbS0s<=a7fh<}2KW#b3&n~p;{;x&D7s-3ZsYL||b7p?T83^B|N3-jEP}k`ULSzhVNxq$Weiey z&j-IZ`e0dG=(HZvNHFfR7#e3rqw*6%zRMAszDIePrq~*m^M9hK=pWwt>9JMn>Oe{r zeTA!xVdVdlWcA16B)$Kk+dE$&8eJBcrY3)-z%=DNdtn$wbIvB>q(6tbQn@|F-j%f# ziJ2GmNXXQcltQe2QqQB$(0>Ep$rf+cbw-=NGXk4PP7RhhJkfV8%EwCD%uL63jq~ro zED5BrBI-EQ%ztvmSFp!T7XQP7v?hORUYzq#$DCBki1M1;^dDnd^&r#lvtWQa{;J$S zI11l=1w$OnMEVR-EAiw8!cPRXwhUH!9n^WGI|8e|#DWV2N@ML&|0+$ECWeH{#Iirs z1?X`iM~{-?^O97HpF|7e#l?mC#X?DYK*3lS%|sOSNPoDo{9bkMxa7~!W~%UzUm$5k zdMmyGh38bLqPvj;xPOrVMSvmQvkwfUs!nlHSH9str8JB-w zyZd(M)*O;AG4m(5oX>hgP0?^?*&@72`?pqcH$i$e8qq8t2S)HF5C{y;y|q4S#1N1m z>_K17`hQZzCNAtPd-1bS&8(Zk(HoF9XE5A68+vJQtL&O&QAww-0h7%0a^n@|=;)+? zVPM(qa--AV(mW6LWd0x@&-iP^y$xT?5o+$uk4(JPpw^?R+w#Dp%Hvx1kRF~>(cIej zw1dcrO=mJHk-UTCBm@>-T-W3XiG-YIC-ymL5q}ouhfoG~z_kmkN`w{Qg6SMgQ_FG- ziARkdF_X&?*g`OHIvd?dYX87!Q8qpn6>_i`7mMWbXDcLn+@!+CBt{xl-8aHf1Q`Ck2-7&uImTj4Ei5)VHTf<9gImX>UkXk5z`0rxX$vBuz|OBbt1__+yozt@|@Jt6~dU~zdW1> zzBCXPv)EKBJpPyz#{6Fz@z>b~dO z)&JF+hUXb6vG?cQRHFQcmFKx}Y9p)U*qJd7a#|e`u4y9n$(VB?HSv_@CoB2>M9j9# zhk&q&A8%2FJPdnF^p$q;{ATFmm4KbVuV{KOb;z;BlvVxWVzCkspw$hUpW93KB z+>K9J{-8uj+SmjQM5d7`eo5-Q9Esx@`|#DeI9cJc?=^=eeAl19w#S#B;a`66;&f&X z0)s}DiR@x}`s`hn=-*^f0AA@}fPZrXEUuPn(P<-s4Fx@aM$Er>j%%Rihs5 zrVp3+lor~q#m9My3h{em?;QoFT_6;H%RmzLyK{6^pit9Gbr6uysZQ7cq~`0mgK_K$ zcv*TZ!pU`t{jm8Tq!zLw$Z`w`h_f=BL$F2g%MV{X3q$KdVoLjhVmaj2@_%fgJOht= z#`l>Bn8LyU0t@z9b5UI?0P0)MSaPQYGYvToFoyp)npwNQ*(CiWgyRk;{9@3p72F>- z)WX4t(wfHdCWAaoJ+-pk7l_+QCB(wsqX-IG{xpL*2vP)w8Y~NMwgK71z?a}48LFaC z{PQIZl@U7==<`<(VYwS~cYo$E>g5{C@5_6-oyEUDD12bJXhVDGzu)Dv2$#$Iq!}4_ zX-A0Fr214D{VP^&Ij}-T*+@8Z84;8|@V;95h)LvI;~pDDBdugRuuT*_XMbOxX1tIAC3f>tu(f*6g@ndg!=nF6MmiVJ$&7-wTS8~59EkIJ%12NZ6eEt<%IhX z)?5@`b}tLqZyDOut7SBAChI|EFx=W!d#*&Y!)0!{#tpj)f1V~{-?YJ6D~p>{hkM zKl%>z2xb8*DREumrhoXp2#Z3Df<>exN+Rk_hcq>P7K?7(ANr!x9KMeig^?t)!X0`| z{wH4;>Z31j33P*O>yWrS*I} zbnk;uJy$>5Xn!du>4+XC^6UTVg^GGz!5MU-Q%*0K=)`IPDW_V{Z`zTunf9~I36pW^ zTXDs8iO|n_NlpbL4@@-Q$+m*>`($P=QsKRQIdXbG6a63UR2D?^U|64qZ z#u!@o+|&{G29P+f7x47gpNezrWV|Qro{-%Pyxd*!dlCA_+$zZ?MEdn}At|q%M7tp| zcy0|M9e)qaoG!zp7K6kn@8m&ADO;U5da9r<`1^D;GK`DTGAhK3Sntb0TBN5OUzoLnU zXALgjCC+pi=PkUV-=F*9yZn}S_yOU%9LY0V!J$)3k#FiMHcphrCf{9PKl*i}ms1l8 zTYvk&%_z1qc2Bq#)tx_v})ScCOQ_P$+p09n>a+`z0fEK zyG)#8kahzN7P@q3W;v5--V&@n;_J4{7=N2s7+?|=!}^emjM`^q6CjF9o#%Tx z$HE7w0h|G-P#=1>GFY37wWc`e?hhbFvZ-(>OV$E{1RllzfykQ0rrzH67y8`dSG-p_ z2*~l3=l>T$`q`Dw8RbTT!_1PyoiGw>1$UH$E}M~ZpIQ8YA&n~A^{%7i9GUpSAAi_G zh_tjUQp^J9%V4C2WWgO%AI`9Q`m#5qCWy#dKmx`%q8{M$wq*f8?7}@)2$#^kg|YO- z&+~n!i6O$Vl0O{wap&L2#kYYXXBsN+7G~LT9dA}Gg_(2rxG9vJPW>{x@+NOGQ--4X z>$+NBlfdp(h{Lx}dQ}&~WhzllTYoau1dYY>W~=X#a;O9*7XI6l*v7mAMQmPLefKUi z@HiZBg2yT~4`Lt})uBwWhg2upw0|uIkS1rp(Wgz3=R9d(#4P)-chcqxM(dAXygP(+zJXE? zUr@+=_EFpEEA-g}@qATc#HoDbarI1nqA4ae7H~YJ<4MIwXopX*cz%+n?FmRiu!e)Q zyc5oz3KK~RY?XW;Y}_@`U@BjsXI0jq47|4>6My{9^Uqd5xhLYaKYv~^68-S8yC+VZ zE#vP+0~B}9dBMzNkd}5cezyN}t}>}SRL1st!^zJLBIs^-3-&symPloq@fbO5cYtO{ z;?XllRV0@tla|ev+o8RK3wpsy1!g z>_m3dv9B6MVvn(N;Kws_s3STl*#&PE{OV9gNdq9lGTt7=ii+R8;k29}vn5Q^Zytq4TOM_1E5l$V1#^Y);z@hA` z=`Lvqf$+dRaW}{n!OK75GVvyVLYw7360LW7-&i-z5tLyGZhF@LC7aZGGrqxQWWE~) z-i4Y%HW&zH3V*fF?J+(;w|-B<`4oB^YPTkA!Q6cJU)&{w zg`q+s6tl-G9OX=~P8n1W>W%5#9*4jMVD^M7IcoF)K>}ErJEe3jmt{$ols+?3*}%Yoy9P7J6g3Uk@(v_iqc(x>QfCXfhWil{UX!n<-NnOrEM{2S)Vyl@CQrKv zZr_-~{Az2iM3vpt^BPCyOYoZhRFC%`8yGSq(tj1=^V$65s!yjBk_pv-m75G92cM0H zwvnNPpXj+Tcr{(9X#Z{hOTlT`g9d(>Ur@(%jv--(Sj4jWzL5F>i06NFq$I=D(mr*t5 z)9ISm~f~jNSvdjsQ?m zwv^Np0r%avs8pJHRMa?in#)=9fIJYv;B;XT)LYm`FXCVU;ojah1g1y6L%VBOMSrKo z#$Gp-fx*cPZdAlTD5A9P@5$LFm=~jpa5LxyjoJNx;kN4$5#2Qak_3#B4)Jj%(9psY zVyj8Ir^D}(lJRqhJmpR;jHu&4br62jQ(mz(!!_3aiNi)Ie_u3~c>F1-`G35qi9U@a zOc^E8rffEe!_C7rf*q;*Hwi2MDaL{)_G5$LQm@=6%S;9ZJp_rbBdTXb0l{Ro=aOEq zEClfS)@Sd|KWUR|k%4p?syFC$1JVEIg&455S>i+)AaR(ht^*UP?>w{2rgdeg;E$$y#nzx!-?kf|8vtCml>5xui2M{01p`m~vMs(sf9Z{iUG zs(B^ya(8|oUB2&J%YekIXupEHZW8+7imYCXKRjF$t`Al3Og36F`1reb{nX(#o#42LVp(Gs<;b6Rb|k1 zHzkRJ_XzfgVF*0DV2KK%l&Q8ETx%%TS%NTj41;m6N6*(lxI8i!P{T5v1a4{7y%4h@ zD=01)ggfnNe*Z2>vDh{KBzwB+MX_{ij`Nh&L&Xx9U51UD_vaQwLMDAd#$dPrUd>;s zYYY>hGgRU@1?JxW)_>4eh_@t1lhM}TRSMifk$f2n&wE;qOCE&18LbxKQHPINVdT@g zmvqt-Anp~Ta)UW-gIvQ1Nm#0~MiU5eNGyTg5;XiZ-2Z@?<{GF$a1> z_i9?Yzs%;&3$HV0RM*GL81f1_{*;fG)K?hHtwN3T8m{)OS$~he>?DijAi}5gMhPjW zCuKYmw~ikflbiHud2X^UW_p?}Vj(%e{;E$<-2KJ*<4=OWtw_=pLVoCos%0bh*p6@w zeLJrR}&&{x5JRAAu5MgA(Q#h*4H8 z8ZrN=1GRkYiy}B-b%?;BRmbovZzmKT1W;5Knl$%LdU1VTa|h67AR1G=e&w`><{?Oy zT$=-3wZL9tgVJ0W;(Z1 zrj*V>)_=VYdWteLE&g}CXbU?cn9I|r)82h?Xe%UeGEWxbC01kZUt*_DP~o#|dni{UD$(PF0v`Qt0A zh-;(%=@h}zejQ&xfq>lww))kzZR=pehd^0i1b_Z>MglKLi8|>T*k~qyLZk<03F}_D zy43VOK=>u`+pbgYw&liv&GMw5$2+CJP$14DY8ju<8<6z)n^TFR|CAssj0O%vCpQb z4TT;l!tu8w1}m!3rAx2iGm{MI6(^-3q<~^2I zqI`indG6N1`~9%Pff}!(IBqH<;HQ#@y3T(BMGiE(2rHKjYlAB#hmQi@_z2R|U1$zJ zOa3IQHzg%lj8!uVv0OIRQ|aucUuNlE_L+Qb=#hb+*!J-~cYx7C3C*f^`VDN(AAg*T zw)Y_$%%m>bo?;GQ1J+9%#)7_RCF}b)gzqTtiAvI~4MTX1(f79g-oMV&9u4 z-i@3)cp)z!!!@0wX;vD`F6-bQZGQ(Mq!Bowb<70O*e} z7**{Xm40)q5OCd;hpnmEEvjnq>nE2WKp8J6iMUqpr!b|2Vw50p{X+na$KPLvz~$#dA3bWZ=>FYc98y&#WEml}6AWp9%MMD9N^#MrHBF zL1KZY5ccwsfj{-Om2|ThGe6`x%M@FcjRNX3$%0tf-9G`k{sDHg9#M91c<)%VWi+>h zk9R6aNnDE@&J*)3A$Y|?G7I~|VludFljRk$zRp0tic8=yvk<7PntwmvO>TQF-+zMI zAVD_CSz6KQ4c+}M-hf zn+M;KW!o)+G$O@!*nbXP*}dJH z@>=Gn__p8%>fOw+`aNIGN|{i5Q=8{jg6RPH%7W;@Zhh|JP1MIDv`o}>EHnOsC5hYp7VgEw-Xi=63qeoi} zGqTYQK63cIY;+3guCW~@ZWEcXVRIv4+fqT%2wXqI;(w7vV5!+-aofeFLYa-@d1RJ~ zKa|7vAd|x#6l5EAo4_60NY+}Qm2WOSSx9rv1Q$e|jaMI`5hvLv+EDBJci+G!iUA;dm6vbjN}ask6kI#zlD$ zkoqMdIe-54Jr>MDkG|-;$Oq-mk9a!)T&zaPD8l$ImmM>=C0|R;y!Q#G{I92+hTO*m z)WU;tw~Hjz{-d0hx^p4@_G!g;Rpv4#tTGNtHJaunj7(`j=p?K^X{}WV0mKR}pcWo6 zJ;dR0kPuxkKM%rV`oXCm1b4>a?%1jEeRJaJ$A1P-@}at6dKeB@ORcs#)-3go2*=hj z)Nw;!uobdNH9SXtu_bxm*7~~ywAn*T=z#M4USZ2A_scJ~VE*QO;SpHj+`Q={9Yg0X z@3ZRcI{rOD0xvtvNL5_8p}QlAk4bJHikFl}u(*@ku~I$wG?Pe`#cuD4J7p_EA)kVs z)qi!0&P9m&a<9!*+s_HNzKWyXq68_FlMC6oBd_iAq4LvBqiW;iY0pR- z@i*=bsCMg&{V2KkM96Alxf_o68rNV1V7rw1mc8mA8|bjOl#3>lCTrYooDy1V_J3Os z)i#Qe02R*}*8MXRm{J)Bq$p0b4*hSwmKi6-wx?L~^6^32(&Nt}@?Jb+_E-Eq=y3~87` z@V-_0e`S)>;zDec=OG>)V-#-@ne1)ekN18vvg_5&lOb@(Ab`c}o%Fe>T`S2Pva0D; zEN>*b3YW|HvF%lcRh(7lvPr>H^tF3g#MPrvdOV8pxv>(dvN!crz7Q?KM(T1-9k>;-K+E@#WDCE5TP$Y5(+pG#q^7BekH5 R00000000~<00000005p1HoE`- diff --git a/testsuite/test_bad2.lz b/testsuite/test_bad2.lz index cce6a3cced41470fbb0338bf6f2cd583bac68d8b..c8ac08c5ca5d41a4017705c26164644b622288ba 100644 GIT binary patch delta 11365 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 delta 11395 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 R00000000~<00000005p1HoE`- diff --git a/testsuite/test_bad3.lz b/testsuite/test_bad3.lz index a1676bbdcc42831a0cf3728f8a1b44260ee93512..3ed893612f0281ff1aa2f2803d885fef731b69d7 100644 GIT binary patch delta 9315 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 R000000090h00000003aD>=6I} delta 9345 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 diff --git a/testsuite/test_bad4.lz b/testsuite/test_bad4.lz index a8f89a334b790947cc73f840b4ddbb03b3bc6d81..c91287197415b935bf809783617fb49cde9daa12 100644 GIT binary patch delta 9312 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 diff --git a/testsuite/test_bad5.lz b/testsuite/test_bad5.lz index 73e0142cbb8c056fdac7fe13ff29590811c4e189..7c703656c6c06a221ad8f2aab82adb55adf999e3 100644 GIT binary patch delta 9309 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 L{wx3h00000#BSb= delta 9339 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 diff --git a/testsuite/test_v0.lz b/testsuite/test_v0.lz deleted file mode 100644 index a09b1e885e665afac43958644069691715aae0db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11540 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 test N-bit errors instead of full byte\n" - " -p, --position= first byte position to test\n" + " -p, --position= first byte position to test [default 0]\n" " -q, --quiet suppress all messages\n" - " -s, --size= number of byte positions to test\n" + " -s, --size= number of byte positions to test [all]\n" " -v, --verbose be verbose (a 2nd -v gives more)\n" - "Examples of : 1 1,2,3 1-4 1,3-5,8\n" + "Examples of : 1 1,2,3 1-4 1,3-5,8 1-3,5-8\n" "\nReport bugs to lzip-bug@nongnu.org\n" "Lzip home page: http://www.nongnu.org/lzip/lzip.html\n" ); } @@ -109,8 +109,8 @@ unsigned long long getnum( const char * const ptr, const unsigned long long llimit, const unsigned long long ulimit ) { - errno = 0; char * tail; + errno = 0; unsigned long long result = strtoull( ptr, &tail, 0 ); if( tail == ptr ) { @@ -172,7 +172,7 @@ public: bool includes( const int i ) const { return ( i >= 1 && i <= 8 && data[i-1] ); } - // Recognized formats: 1 1,2,3 1-4 1,3-5,8 + // Recognized formats: 1 1,2,3 1-4 1,3-5,8 1-3,5-8 bool parse( const char * p ) { for( int i = 0; i < 8; ++i ) data[i] = false;