Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package wimlib for openSUSE:Factory checked 
in at 2021-07-05 22:23:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/wimlib (Old)
 and      /work/SRC/openSUSE:Factory/.wimlib.new.2625 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "wimlib"

Mon Jul  5 22:23:18 2021 rev:5 rq:904132 version:1.13.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/wimlib/wimlib.changes    2020-12-12 
20:32:47.129878404 +0100
+++ /work/SRC/openSUSE:Factory/.wimlib.new.2625/wimlib.changes  2021-07-05 
22:24:05.721204085 +0200
@@ -1,0 +2,13 @@
+Mon Jul  5 07:36:38 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 1.13.4:
+  * wimsplit now prints progress messages regularly rather than just once
+    per WIM part.
+
+  * Added support for a data recovery mode which causes files to be
+    extracted even if they are corrupted.  The option is --recover-data for
+    wimapply and wimextract, and WIMLIB_EXTRACT_FLAG_RECOVER_DATA for the
+    library.  Note that this option won't help with all types of corruption;
+    some types of corruption will still cause a fatal error.
+
+-------------------------------------------------------------------

Old:
----
  wimlib-1.13.3.tar.gz

New:
----
  wimlib-1.13.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ wimlib.spec ++++++
--- /var/tmp/diff_new_pack.AMR21n/_old  2021-07-05 22:24:06.213200279 +0200
+++ /var/tmp/diff_new_pack.AMR21n/_new  2021-07-05 22:24:06.213200279 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package wimlib
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,10 +18,10 @@
 
 %define so_version 15
 Name:           wimlib
-Version:        1.13.3
+Version:        1.13.4
 Release:        0
 Summary:        Library to extract, create, modify, and mount WIM files
-License:        GPL-3.0-or-later AND LGPL-3.0-or-later AND CC0-1.0
+License:        CC0-1.0 AND GPL-3.0-or-later AND LGPL-3.0-or-later
 Group:          Development/Libraries/C and C++
 URL:            https://wimlib.net
 Source:         https://wimlib.net/downloads/wimlib-%{version}.tar.gz

++++++ wimlib-1.13.3.tar.gz -> wimlib-1.13.4.tar.gz ++++++
++++ 13040 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/Makefile.am new/wimlib-1.13.4/Makefile.am
--- old/wimlib-1.13.3/Makefile.am       2020-10-27 04:49:10.000000000 +0100
+++ new/wimlib-1.13.4/Makefile.am       2021-04-19 06:35:01.000000000 +0200
@@ -200,7 +200,7 @@
        $(LIBFUSE_CFLAGS)       \
        $(LIBCRYPTO_CFLAGS)
 
-libwim_la_LDFLAGS = $(AM_LDFLAGS) -version-info 33:0:18
+libwim_la_LDFLAGS = $(AM_LDFLAGS) -version-info 34:0:19
 
 libwim_la_LIBADD =             \
        $(PTHREAD_LIBS)         \
@@ -340,7 +340,8 @@
        tests/security_descriptor_1.base64      \
        tests/security_descriptor_1.bin         \
        tests/security_descriptor_2.base64      \
-       tests/security_descriptor_2.bin
+       tests/security_descriptor_2.bin         \
+       tests/wims
 
 if WINDOWS_NATIVE_BUILD
 # Tests are run manually for Windows builds.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/NEWS new/wimlib-1.13.4/NEWS
--- old/wimlib-1.13.3/NEWS      2020-10-27 04:53:59.000000000 +0100
+++ new/wimlib-1.13.4/NEWS      2021-04-19 06:35:01.000000000 +0200
@@ -1,3 +1,13 @@
+Version 1.13.4:
+       wimsplit now prints progress messages regularly rather than just once
+       per WIM part.
+
+       Added support for a data recovery mode which causes files to be
+       extracted even if they are corrupted.  The option is --recover-data for
+       wimapply and wimextract, and WIMLIB_EXTRACT_FLAG_RECOVER_DATA for the
+       library.  Note that this option won't help with all types of corruption;
+       some types of corruption will still cause a fatal error.
+
 Version 1.13.3:
        On Windows, improved performance of capturing an entire drive in some
        cases.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/README new/wimlib-1.13.4/README
--- old/wimlib-1.13.3/README    2020-10-27 04:49:10.000000000 +0100
+++ new/wimlib-1.13.4/README    2021-04-19 06:35:01.000000000 +0200
@@ -1,6 +1,6 @@
                                   INTRODUCTION
 
-This is wimlib version 1.13.3 (October 2020).  wimlib is a C library for
+This is wimlib version 1.13.4 (April 2021).  wimlib is a C library for
 creating, modifying, extracting, and mounting files in the Windows Imaging
 Format (WIM files).  wimlib and its command-line frontend 'wimlib-imagex'
 provide a free and cross-platform alternative to Microsoft's WIMGAPI, ImageX,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/config.h.in new/wimlib-1.13.4/config.h.in
--- old/wimlib-1.13.3/config.h.in       2020-10-27 04:54:51.000000000 +0100
+++ new/wimlib-1.13.4/config.h.in       2021-04-19 06:35:44.000000000 +0200
@@ -72,9 +72,6 @@
 /* Define to 1 if you have the <machine/endian.h> header file. */
 #undef HAVE_MACHINE_ENDIAN_H
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
 /* Define to 1 if you have the `mempcpy' function. */
 #undef HAVE_MEMPCPY
 
@@ -109,6 +106,9 @@
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
@@ -185,7 +185,9 @@
    your system. */
 #undef PTHREAD_CREATE_JOINABLE
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
 /* Version number of package */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/configure.ac new/wimlib-1.13.4/configure.ac
--- old/wimlib-1.13.3/configure.ac      2020-10-27 04:49:10.000000000 +0100
+++ new/wimlib-1.13.4/configure.ac      2021-04-19 06:35:01.000000000 +0200
@@ -1,6 +1,6 @@
 ###############################################################################
 
-AC_INIT([wimlib], [1.13.3], [https://wimlib.net/forums/])
+AC_INIT([wimlib], [1.13.4], [https://wimlib.net/forums/])
 AC_CONFIG_SRCDIR([src/wim.c])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_AUX_DIR([build-aux])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/mkwinpeimg.1 new/wimlib-1.13.4/doc/man1/mkwinpeimg.1
--- old/wimlib-1.13.3/doc/man1/mkwinpeimg.1     2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/mkwinpeimg.1     2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH MKWINPEIMG "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH MKWINPEIMG "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 mkwinpeimg \- Make a customized bootable image of Windows PE
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimapply.1 new/wimlib-1.13.4/doc/man1/wimapply.1
--- old/wimlib-1.13.3/doc/man1/wimapply.1       2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimapply.1       2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMAPPLY "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMAPPLY "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimapply \- Apply a WIM image
 .SH SYNOPSIS
@@ -355,15 +355,22 @@
 In addition, wimlib has a hardcoded list of files for which it knows, for
 compatibility with the Windows bootloader, to override the requested 
compression
 format.
+.TP
+\fB--recover-data\fR
+If a file is corrupted (its stored hash doesn't match its actual hash, or some
+parts of it can't be decompressed), extract the corrupted file anyway with a
+warning, rather than aborting with an error.  This may be useful to recover 
data
+if a WIM archive was corrupted.  Note that recovering data is not guaranteed to
+succeed, as it depends on the type of corruption that occurred.
 .SH NOTES
 \fIData integrity\fR: WIM files include checksums of file data.  To detect
 accidental (non-malicious) data corruption, wimlib calculates the checksum of
 every file it extracts and issues an error if it does not have the expected
-value.  (This default behavior seems equivalent to the \fB/verify\fR option of
-ImageX.)  In addition, a WIM file can include an integrity table (extra
-checksums) over the raw data of the entire WIM file.  For performance reasons
-wimlib does not check the integrity table by default, but the \fB--check\fR
-option can be passed to make it do so.
+value, unless the \fB--recover-data\fR option is given.  (This default behavior
+seems equivalent to the \fB/verify\fR option of ImageX.)  In addition, a WIM
+file can include an integrity table (extra checksums) over the raw data of the
+entire WIM file.  For performance reasons wimlib does not check the integrity
+table by default, but the \fB--check\fR option can be passed to make it do so.
 .PP
 \fIESD files\fR: wimlib can extract files from solid-compressed WIMs, or "ESD"
 (.esd) files, just like from normal WIM (.wim) files.  However, Microsoft
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimcapture.1 new/wimlib-1.13.4/doc/man1/wimcapture.1
--- old/wimlib-1.13.3/doc/man1/wimcapture.1     2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimcapture.1     2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMCAPTURE "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMCAPTURE "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimcapture, wimappend \- Capture or append a WIM image
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimdelete.1 new/wimlib-1.13.4/doc/man1/wimdelete.1
--- old/wimlib-1.13.3/doc/man1/wimdelete.1      2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimdelete.1      2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMDELETE "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMDELETE "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimdelete \- Delete an image from a WIM archive
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimdir.1 new/wimlib-1.13.4/doc/man1/wimdir.1
--- old/wimlib-1.13.3/doc/man1/wimdir.1 2020-10-27 04:49:10.000000000 +0100
+++ new/wimlib-1.13.4/doc/man1/wimdir.1 2021-04-19 06:35:01.000000000 +0200
@@ -1,4 +1,4 @@
-.TH WIMDIR "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMDIR "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimdir \- List the files contained in a WIM image
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimexport.1 new/wimlib-1.13.4/doc/man1/wimexport.1
--- old/wimlib-1.13.3/doc/man1/wimexport.1      2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimexport.1      2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMEXPORT "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMEXPORT "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimexport \- Export image(s) from a WIM archive
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimextract.1 new/wimlib-1.13.4/doc/man1/wimextract.1
--- old/wimlib-1.13.3/doc/man1/wimextract.1     2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimextract.1     2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMEXTRACT "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMEXTRACT "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimextract \- Extract files from a WIM image
 .SH SYNOPSIS
@@ -152,6 +152,9 @@
 .TP
 \fB--compact\fR=\fIFORMAT\fR
 See the documentation for this option to \fBwimapply\fR(1).
+.TP
+\fB--recover-data\fR
+See the documentation for this option to \fBwimapply\fR(1).
 .SH NOTES
 See \fBwimapply\fR(1) for information about what data and metadata are 
extracted
 on UNIX-like systems versus on Windows.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wiminfo.1 new/wimlib-1.13.4/doc/man1/wiminfo.1
--- old/wimlib-1.13.3/doc/man1/wiminfo.1        2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wiminfo.1        2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMINFO "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMINFO "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wiminfo \- Display or change information about a WIM file or image
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimjoin.1 new/wimlib-1.13.4/doc/man1/wimjoin.1
--- old/wimlib-1.13.3/doc/man1/wimjoin.1        2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimjoin.1        2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMJOIN "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMJOIN "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimjoin\- Join a split WIM into a standalone WIM
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimlib-imagex.1 
new/wimlib-1.13.4/doc/man1/wimlib-imagex.1
--- old/wimlib-1.13.3/doc/man1/wimlib-imagex.1  2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimlib-imagex.1  2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMLIB-IMAGEX 1 "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMLIB-IMAGEX 1 "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimlib-imagex \- Extract, create, modify, or mount a WIM archive
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimmount.1 new/wimlib-1.13.4/doc/man1/wimmount.1
--- old/wimlib-1.13.3/doc/man1/wimmount.1       2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimmount.1       2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMMOUNT "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMMOUNT "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimmount, wimmountrw, wimunmount \- Mount or unmount a WIM image
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimoptimize.1 
new/wimlib-1.13.4/doc/man1/wimoptimize.1
--- old/wimlib-1.13.3/doc/man1/wimoptimize.1    2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimoptimize.1    2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMOPTIMIZE "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMOPTIMIZE "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimoptimize \- Optimize a WIM archive
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimsplit.1 new/wimlib-1.13.4/doc/man1/wimsplit.1
--- old/wimlib-1.13.3/doc/man1/wimsplit.1       2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimsplit.1       2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMSPLIT "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMSPLIT "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimsplit \- Split a WIM archive into multiple parts
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimupdate.1 new/wimlib-1.13.4/doc/man1/wimupdate.1
--- old/wimlib-1.13.3/doc/man1/wimupdate.1      2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimupdate.1      2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMUPDATE "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMUPDATE "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimupdate \- Update a WIM image
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/doc/man1/wimverify.1 new/wimlib-1.13.4/doc/man1/wimverify.1
--- old/wimlib-1.13.3/doc/man1/wimverify.1      2020-10-27 04:49:10.000000000 
+0100
+++ new/wimlib-1.13.4/doc/man1/wimverify.1      2021-04-19 06:35:01.000000000 
+0200
@@ -1,4 +1,4 @@
-.TH WIMVERIFY "1" "October 2020" "wimlib 1.13.3" "User Commands"
+.TH WIMVERIFY "1" "April 2021" "wimlib 1.13.4" "User Commands"
 .SH NAME
 wimverify \- Verify a WIM archive
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/include/wimlib/blob_table.h 
new/wimlib-1.13.4/include/wimlib/blob_table.h
--- old/wimlib-1.13.3/include/wimlib/blob_table.h       2020-02-21 
05:14:39.000000000 +0100
+++ new/wimlib-1.13.4/include/wimlib/blob_table.h       2021-04-07 
05:55:50.000000000 +0200
@@ -141,6 +141,9 @@
        /* 1 iff the SHA-1 message digest of this blob is unknown.  */
        u16 unhashed : 1;
 
+       /* 1 iff this blob has failed its checksum.  */
+       u16 corrupted : 1;
+
        /* Temporary fields used when writing blobs; set as documented for
         * prepare_blob_list_for_write().  */
        u16 unique_size : 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/include/wimlib/ntfs_3g.h 
new/wimlib-1.13.4/include/wimlib/ntfs_3g.h
--- old/wimlib-1.13.3/include/wimlib/ntfs_3g.h  2017-09-20 04:55:16.000000000 
+0200
+++ new/wimlib-1.13.4/include/wimlib/ntfs_3g.h  2021-04-06 21:48:32.000000000 
+0200
@@ -11,7 +11,8 @@
 
 extern int
 read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size,
-                          const struct consume_chunk_callback *cb);
+                          const struct consume_chunk_callback *cb,
+                          bool recover_data);
 
 extern struct ntfs_location *
 clone_ntfs_location(const struct ntfs_location *loc);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/include/wimlib/resource.h 
new/wimlib-1.13.4/include/wimlib/resource.h
--- old/wimlib-1.13.3/include/wimlib/resource.h 2017-09-20 04:55:16.000000000 
+0200
+++ new/wimlib-1.13.4/include/wimlib/resource.h 2021-04-07 05:32:59.000000000 
+0200
@@ -273,6 +273,7 @@
 #define VERIFY_BLOB_HASHES             0x1
 #define COMPUTE_MISSING_BLOB_HASHES    0x2
 #define BLOB_LIST_ALREADY_SORTED       0x4
+#define RECOVER_DATA                   0x8
 
 extern int
 read_blob_list(struct list_head *blob_list, size_t list_head_offset,
@@ -280,18 +281,19 @@
 
 extern int
 read_blob_with_cbs(struct blob_descriptor *blob,
-                  const struct read_blob_callbacks *cbs);
+                  const struct read_blob_callbacks *cbs, bool recover_data);
 
 extern int
 read_blob_with_sha1(struct blob_descriptor *blob,
-                   const struct read_blob_callbacks *cbs);
+                   const struct read_blob_callbacks *cbs, bool recover_data);
 
 extern int
 extract_blob_prefix_to_fd(struct blob_descriptor *blob, u64 size,
                          struct filedes *fd);
 
 extern int
-extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd);
+extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd,
+                  bool recover_data);
 
 /* Miscellaneous blob functions.  */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/include/wimlib/win32.h 
new/wimlib-1.13.4/include/wimlib/win32.h
--- old/wimlib-1.13.3/include/wimlib/win32.h    2017-09-20 04:55:16.000000000 
+0200
+++ new/wimlib-1.13.4/include/wimlib/win32.h    2021-04-06 21:48:32.000000000 
+0200
@@ -25,7 +25,8 @@
 
 extern int
 read_windows_file_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct consume_chunk_callback *cb);
+                        const struct consume_chunk_callback *cb,
+                        bool recover_data);
 
 extern int
 win32_global_init(int init_flags);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/include/wimlib.h new/wimlib-1.13.4/include/wimlib.h
--- old/wimlib-1.13.3/include/wimlib.h  2020-10-27 04:49:10.000000000 +0100
+++ new/wimlib-1.13.4/include/wimlib.h  2021-04-19 06:35:01.000000000 +0200
@@ -11,7 +11,7 @@
 /**
  * @mainpage
  *
- * This is the documentation for the library interface of wimlib 1.13.3, a C
+ * This is the documentation for the library interface of wimlib 1.13.4, a C
  * library for creating, modifying, extracting, and mounting files in the
  * Windows Imaging (WIM) format.  This documentation is intended for developers
  * only.  If you have installed wimlib and want to know how to use the @b
@@ -411,7 +411,7 @@
 #define WIMLIB_MINOR_VERSION 13
 
 /** Patch version of the library (for example, the 5 in 1.2.5). */
-#define WIMLIB_PATCH_VERSION 3
+#define WIMLIB_PATCH_VERSION 4
 
 #ifdef __cplusplus
 extern "C" {
@@ -649,7 +649,8 @@
         * to ::wimlib_progress_info.write_streams.  This message may be
         * received many times while the WIM file is being written or appended
         * to with wimlib_write(), wimlib_overwrite(), or wimlib_write_to_fd().
-        */
+        * Since wimlib v1.13.4 it will also be received when a split WIM part
+        * is being written by wimlib_split().  */
        WIMLIB_PROGRESS_MSG_WRITE_STREAMS = 12,
 
        /** Per-image metadata is about to be written to the WIM file.  @p info
@@ -825,7 +826,8 @@
                /** The number of bytes of file data that have been written so
                 * far.  This starts at 0 and ends at @p total_bytes.  This
                 * number is the uncompressed size; the actual size may be lower
-                * due to compression.  */
+                * due to compression.  See @p completed_compressed_bytes for
+                * the compressed size.  */
                uint64_t completed_bytes;
 
                /** The number of distinct file data "blobs" that have been
@@ -848,6 +850,10 @@
 
                /** This is currently broken and will always be 0.  */
                uint32_t completed_parts;
+
+               /** Since wimlib v1.13.4: Like @p completed_bytes, but counts
+                * the compressed size.  */
+               uint64_t completed_compressed_bytes;
        } write_streams;
 
        /** Valid on messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN,
@@ -1922,6 +1928,10 @@
  * wimlib_extract_paths() when passed multiple paths.  */
 #define WIMLIB_EXTRACT_FLAG_NTFS                       0x00000001
 
+/** Since wimlib v1.13.4: Don't consider corrupted files to be an error.  Just
+ * extract them in whatever form we can.  */
+#define WIMLIB_EXTRACT_FLAG_RECOVER_DATA               0x00000002
+
 /** UNIX-like systems only:  Extract UNIX-specific metadata captured with
  * ::WIMLIB_ADD_FLAG_UNIX_DATA.  */
 #define WIMLIB_EXTRACT_FLAG_UNIX_DATA                  0x00000020
@@ -4305,7 +4315,9 @@
  * If a progress function is registered with @p wim, then for each split WIM
  * part that is written it will receive the messages
  * ::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART and
- * ::WIMLIB_PROGRESS_MSG_SPLIT_END_PART.
+ * ::WIMLIB_PROGRESS_MSG_SPLIT_END_PART.  Since wimlib v1.13.4 it will also
+ * receive ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages while writing each 
part;
+ * these messages will report the progress of the current part only.
  */
 extern int
 wimlib_split(WIMStruct *wim,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/programs/imagex.c new/wimlib-1.13.4/programs/imagex.c
--- old/wimlib-1.13.3/programs/imagex.c 2020-05-22 08:31:25.000000000 +0200
+++ new/wimlib-1.13.4/programs/imagex.c 2021-04-19 05:13:26.000000000 +0200
@@ -6,7 +6,7 @@
  */
 
 /*
- * Copyright (C) 2012-2018 Eric Biggers
+ * Copyright (C) 2012-2021 Eric Biggers
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -202,6 +202,7 @@
        IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION,
        IMAGEX_REBUILD_OPTION,
        IMAGEX_RECOMPRESS_OPTION,
+       IMAGEX_RECOVER_DATA_OPTION,
        IMAGEX_RECURSIVE_OPTION,
        IMAGEX_REF_OPTION,
        IMAGEX_RPFIX_OPTION,
@@ -239,6 +240,7 @@
        {T("include-invalid-names"), no_argument,       NULL, 
IMAGEX_INCLUDE_INVALID_NAMES_OPTION},
        {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
        {T("compact"),     required_argument, NULL, IMAGEX_COMPACT_OPTION},
+       {T("recover-data"), no_argument,      NULL, IMAGEX_RECOVER_DATA_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -336,6 +338,7 @@
        {T("preserve-dir-structure"), no_argument, NULL, 
IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION},
        {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
        {T("compact"),     required_argument, NULL, IMAGEX_COMPACT_OPTION},
+       {T("recover-data"), no_argument,      NULL, IMAGEX_RECOVER_DATA_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -1163,6 +1166,31 @@
                last_scan_progress = *scan;
        }
 }
+
+static struct wimlib_progress_info_split last_split_progress;
+
+static void
+report_split_progress(uint64_t bytes_completed_in_part)
+{
+       uint64_t completed_bytes = last_split_progress.completed_bytes +
+                                  bytes_completed_in_part;
+       unsigned percent_done = TO_PERCENT(completed_bytes,
+                                          last_split_progress.total_bytes);
+       unsigned unit_shift;
+       const tchar *unit_name;
+
+       unit_shift = get_unit(last_split_progress.total_bytes, &unit_name);
+       imagex_printf(T("\rSplitting WIM: %"PRIu64" %"TS" of "
+                       "%"PRIu64" %"TS" (%u%%) written, part %u of %u"),
+                     completed_bytes >> unit_shift,
+                     unit_name,
+                     last_split_progress.total_bytes >> unit_shift,
+                     unit_name,
+                     percent_done,
+                     last_split_progress.cur_part_number,
+                     last_split_progress.total_parts);
+}
+
 /* Progress callback function passed to various wimlib functions. */
 static enum wimlib_progress_status
 imagex_progress_func(enum wimlib_progress_msg msg,
@@ -1175,6 +1203,12 @@
 
        switch (msg) {
        case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
+               if (last_split_progress.total_bytes != 0) {
+                       /* wimlib_split() in progress; use the split-specific
+                        * progress message.  */
+                       
report_split_progress(info->write_streams.completed_compressed_bytes);
+                       break;
+               }
                {
                        static bool started;
                        if (!started) {
@@ -1330,26 +1364,9 @@
                }
                break;
        case WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART:
-               percent_done = TO_PERCENT(info->split.completed_bytes,
-                                         info->split.total_bytes);
-               unit_shift = get_unit(info->split.total_bytes, &unit_name);
-               imagex_printf(T("Writing \"%"TS"\" (part %u of %u): %"PRIu64" 
%"TS" of "
-                         "%"PRIu64" %"TS" (%u%%) written\n"),
-                       info->split.part_name,
-                       info->split.cur_part_number,
-                       info->split.total_parts,
-                       info->split.completed_bytes >> unit_shift,
-                       unit_name,
-                       info->split.total_bytes >> unit_shift,
-                       unit_name,
-                       percent_done);
-               break;
        case WIMLIB_PROGRESS_MSG_SPLIT_END_PART:
-               if (info->split.completed_bytes == info->split.total_bytes) {
-                       imagex_printf(T("Finished writing split WIM part %u of 
%u\n"),
-                               info->split.cur_part_number,
-                               info->split.total_parts);
-               }
+               last_split_progress = info->split;
+               report_split_progress(0);
                break;
        case WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND:
                switch (info->update.command->op) {
@@ -1733,6 +1750,9 @@
                        if (ret)
                                goto out_free_refglobs;
                        break;
+               case IMAGEX_RECOVER_DATA_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_RECOVER_DATA;
+                       break;
                default:
                        goto out_usage;
                }
@@ -3280,6 +3300,9 @@
                        if (ret)
                                goto out_free_refglobs;
                        break;
+               case IMAGEX_RECOVER_DATA_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_RECOVER_DATA;
+                       break;
                default:
                        goto out_usage;
                }
@@ -4019,6 +4042,7 @@
                goto out;
 
        ret = wimlib_split(wim, argv[1], part_size, write_flags);
+       tprintf(T("\nFinished splitting \"%"TS"\"\n"), argv[0]);
        wimlib_free(wim);
 out:
        return ret;
@@ -4469,7 +4493,7 @@
 "                    [--check] [--ref=\"GLOB\"] [--no-acls] [--strict-acls]\n"
 "                    [--no-attributes] [--rpfix] [--norpfix]\n"
 "                    [--include-invalid-names] [--wimboot] [--unix-data]\n"
-"                    [--compact=FORMAT]\n"
+"                    [--compact=FORMAT] [--recover-data]\n"
 ),
 [CMD_CAPTURE] =
 T(
@@ -4502,8 +4526,8 @@
 "    %"TS" WIMFILE IMAGE [(PATH | @LISTFILE)...]\n"
 "                    [--check] [--ref=\"GLOB\"] [--dest-dir=CMD_DIR]\n"
 "                    [--to-stdout] [--no-acls] [--strict-acls]\n"
-"                    [--no-attributes] [--include-invalid-names]\n"
-"                    [--no-globs] [--nullglob] [--preserve-dir-structure]\n"
+"                    [--no-attributes] [--include-invalid-names] 
[--no-globs]\n"
+"                    [--nullglob] [--preserve-dir-structure] 
[--recover-data]\n"
 ),
 [CMD_INFO] =
 T(
@@ -4587,7 +4611,7 @@
        static const tchar * const fmt =
        T(
 "wimlib-imagex " PACKAGE_VERSION " (using wimlib %"TS")\n"
-"Copyright (C) 2012-2018 Eric Biggers\n"
+"Copyright (C) 2012-2021 Eric Biggers\n"
 "License GPLv3+; GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>.\n"
 "This is free software: you are free to change and redistribute it.\n"
 "There is NO WARRANTY, to the extent permitted by law.\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/programs/mkwinpeimg new/wimlib-1.13.4/programs/mkwinpeimg
--- old/wimlib-1.13.3/programs/mkwinpeimg       2020-10-27 04:54:57.000000000 
+0100
+++ new/wimlib-1.13.4/programs/mkwinpeimg       2021-04-19 06:35:44.000000000 
+0200
@@ -20,7 +20,7 @@
 
 script_name="$(basename "$0")"
 PREFIX_REG="::"
-WIMLIB_VERSION=1.13.3
+WIMLIB_VERSION=1.13.4
 
 calc_columns () {
        STAT_COL=80
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/src/extract.c new/wimlib-1.13.4/src/extract.c
--- old/wimlib-1.13.3/src/extract.c     2018-07-21 22:32:01.000000000 +0200
+++ new/wimlib-1.13.4/src/extract.c     2021-04-19 06:35:01.000000000 +0200
@@ -72,6 +72,7 @@
 /* Keep in sync with wimlib.h  */
 #define WIMLIB_EXTRACT_MASK_PUBLIC                             \
        (WIMLIB_EXTRACT_FLAG_NTFS                       |       \
+        WIMLIB_EXTRACT_FLAG_RECOVER_DATA               |       \
         WIMLIB_EXTRACT_FLAG_UNIX_DATA                  |       \
         WIMLIB_EXTRACT_FLAG_NO_ACLS                    |       \
         WIMLIB_EXTRACT_FLAG_STRICT_ACLS                |       \
@@ -310,7 +311,9 @@
                    && (blob->out_refcnt))
                {
                        wim_reshdr_to_desc_and_blob(&reshdr, ctx->wim, &rdesc, 
blob);
-                       ret = read_blob_with_sha1(blob, cbs);
+                       ret = read_blob_with_sha1(blob, cbs,
+                                                 ctx->extract_flags &
+                                                 
WIMLIB_EXTRACT_FLAG_RECOVER_DATA);
                        blob_unset_is_located_in_wim_resource(blob);
                        if (ret)
                                return ret;
@@ -504,18 +507,39 @@
 
        for (u32 i = 0; i < orig_blob->out_refcnt; i++) {
                tmpfile_blob.inline_blob_extraction_targets[0] = targets[i];
-               ret = read_blob_with_cbs(&tmpfile_blob, cbs);
+               ret = read_blob_with_cbs(&tmpfile_blob, cbs, false);
                if (ret)
                        return ret;
        }
        return 0;
 }
 
+static void
+warn_about_corrupted_file(struct wim_dentry *dentry,
+                         const struct wim_inode_stream *stream)
+{
+       WARNING("Corruption in %s\"%"TS"\"!  Extracting anyway since data 
recovery mode is enabled.",
+               stream_is_unnamed_data_stream(stream) ? "" : "alternate stream 
of ",
+               dentry_full_path(dentry));
+}
+
 static int
 end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx)
 {
        struct apply_ctx *ctx = _ctx;
 
+       if ((ctx->extract_flags & WIMLIB_EXTRACT_FLAG_RECOVER_DATA) &&
+           !status && blob->corrupted) {
+               const struct blob_extraction_target *targets =
+                       blob_extraction_targets(blob);
+               for (u32 i = 0; i < blob->out_refcnt; i++) {
+                       struct wim_dentry *dentry =
+                               inode_first_extraction_dentry(targets[i].inode);
+
+                       warn_about_corrupted_file(dentry, targets[i].stream);
+               }
+       }
+
        if (unlikely(filedes_valid(&ctx->tmpfile_fd))) {
                filedes_close(&ctx->tmpfile_fd);
                if (!status)
@@ -560,10 +584,15 @@
        if (ctx->extract_flags & WIMLIB_EXTRACT_FLAG_FROM_PIPE) {
                return read_blobs_from_pipe(ctx, &wrapper_cbs);
        } else {
+               int flags = VERIFY_BLOB_HASHES;
+
+               if (ctx->extract_flags & WIMLIB_EXTRACT_FLAG_RECOVER_DATA)
+                       flags |= RECOVER_DATA;
+
                return read_blob_list(&ctx->blob_list,
                                      offsetof(struct blob_descriptor,
                                               extraction_list),
-                                     &wrapper_cbs, VERIFY_BLOB_HASHES);
+                                     &wrapper_cbs, flags);
        }
 }
 
@@ -574,11 +603,13 @@
  * unnamed data stream only.  */
 static int
 extract_dentry_to_stdout(struct wim_dentry *dentry,
-                        const struct blob_table *blob_table)
+                        const struct blob_table *blob_table, int extract_flags)
 {
        struct wim_inode *inode = dentry->d_inode;
        struct blob_descriptor *blob;
        struct filedes _stdout;
+       bool recover = (extract_flags & WIMLIB_EXTRACT_FLAG_RECOVER_DATA);
+       int ret;
 
        if (inode->i_attributes & (FILE_ATTRIBUTE_REPARSE_POINT |
                                   FILE_ATTRIBUTE_DIRECTORY |
@@ -598,15 +629,23 @@
        }
 
        filedes_init(&_stdout, STDOUT_FILENO);
-       return extract_blob_to_fd(blob, &_stdout);
+       ret = extract_blob_to_fd(blob, &_stdout, recover);
+       if (ret)
+               return ret;
+       if (recover && blob->corrupted)
+               warn_about_corrupted_file(dentry,
+                                         inode_get_unnamed_data_stream(inode));
+       return 0;
 }
 
 static int
 extract_dentries_to_stdout(struct wim_dentry **dentries, size_t num_dentries,
-                          const struct blob_table *blob_table)
+                          const struct blob_table *blob_table,
+                          int extract_flags)
 {
        for (size_t i = 0; i < num_dentries; i++) {
-               int ret = extract_dentry_to_stdout(dentries[i], blob_table);
+               int ret = extract_dentry_to_stdout(dentries[i], blob_table,
+                                                  extract_flags);
                if (ret)
                        return ret;
        }
@@ -1446,7 +1485,8 @@
 
        if (extract_flags & WIMLIB_EXTRACT_FLAG_TO_STDOUT) {
                ret = extract_dentries_to_stdout(trees, num_trees,
-                                                wim->blob_table);
+                                                wim->blob_table,
+                                                extract_flags);
                goto out;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/src/ntfs-3g_capture.c new/wimlib-1.13.4/src/ntfs-3g_capture.c
--- old/wimlib-1.13.3/src/ntfs-3g_capture.c     2018-05-02 05:38:31.000000000 
+0200
+++ new/wimlib-1.13.4/src/ntfs-3g_capture.c     2021-04-07 05:56:07.000000000 
+0200
@@ -117,7 +117,8 @@
 
 int
 read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size,
-                          const struct consume_chunk_callback *cb)
+                          const struct consume_chunk_callback *cb,
+                          bool recover_data)
 {
        const struct ntfs_location *loc = blob->ntfs_loc;
        ntfs_volume *vol = loc->volume->vol;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/src/resource.c new/wimlib-1.13.4/src/resource.c
--- old/wimlib-1.13.3/src/resource.c    2017-09-20 04:55:17.000000000 +0200
+++ new/wimlib-1.13.4/src/resource.c    2021-04-07 06:31:47.000000000 +0200
@@ -83,6 +83,34 @@
        u64 size;
 };
 
+static int
+decompress_chunk(const void *cbuf, u32 chunk_csize, u8 *ubuf, u32 chunk_usize,
+                struct wimlib_decompressor *decompressor, bool recover_data)
+{
+       int res = wimlib_decompress(cbuf, chunk_csize, ubuf, chunk_usize,
+                                   decompressor);
+       if (likely(res == 0))
+               return 0;
+
+       if (recover_data) {
+               WARNING("Failed to decompress data!  Continuing anyway since 
data recovery mode is enabled.");
+
+               /* Continue on with *something*.  In the worst case just use a
+                * zeroed buffer.  But, try to fill as much of it with
+                * decompressed data as we can.  This works because if the
+                * corruption isn't located right at the beginning of the
+                * compressed chunk, wimlib_decompress() may write some correct
+                * output at the beginning even if it fails later.  */
+               memset(ubuf, 0, chunk_usize);
+               (void)wimlib_decompress(cbuf, chunk_csize, ubuf,
+                                       chunk_usize, decompressor);
+               return 0;
+       }
+       ERROR("Failed to decompress data!");
+       errno = EINVAL;
+       return WIMLIB_ERR_DECOMPRESSION;
+}
+
 /*
  * Read data from a compressed WIM resource.
  *
@@ -98,6 +126,9 @@
  *     the data being read.  Each call provides the next chunk of the requested
  *     data, uncompressed.  Each chunk will be nonempty and will not cross
  *     range boundaries but otherwise will be of unspecified size.
+ * @recover_data
+ *     If a chunk can't be fully decompressed due to being corrupted, continue
+ *     with whatever data can be recovered rather than return an error.
  *
  * Possible return values:
  *
@@ -114,7 +145,8 @@
 read_compressed_wim_resource(const struct wim_resource_descriptor * const 
rdesc,
                             const struct data_range * const ranges,
                             const size_t num_ranges,
-                            const struct consume_chunk_callback *cb)
+                            const struct consume_chunk_callback *cb,
+                            bool recover_data)
 {
        int ret;
        u64 *chunk_offsets = NULL;
@@ -446,17 +478,12 @@
                                goto read_error;
 
                        if (read_buf == cbuf) {
-                               ret = wimlib_decompress(cbuf,
-                                                       chunk_csize,
-                                                       ubuf,
-                                                       chunk_usize,
-                                                       decompressor);
-                               if (unlikely(ret)) {
-                                       ERROR("Failed to decompress data!");
-                                       ret = WIMLIB_ERR_DECOMPRESSION;
-                                       errno = EINVAL;
+                               ret = decompress_chunk(cbuf, chunk_csize,
+                                                      ubuf, chunk_usize,
+                                                      decompressor,
+                                                      recover_data);
+                               if (unlikely(ret))
                                        goto out_cleanup;
-                               }
                        }
                        cur_read_offset += chunk_csize;
 
@@ -592,7 +619,8 @@
 static int
 read_partial_wim_resource(const struct wim_resource_descriptor *rdesc,
                          const u64 offset, const u64 size,
-                         const struct consume_chunk_callback *cb)
+                         const struct consume_chunk_callback *cb,
+                         bool recover_data)
 {
        if (rdesc->flags & (WIM_RESHDR_FLAG_COMPRESSED |
                            WIM_RESHDR_FLAG_SOLID))
@@ -604,7 +632,8 @@
                        .offset = offset,
                        .size = size,
                };
-               return read_compressed_wim_resource(rdesc, &range, 1, cb);
+               return read_compressed_wim_resource(rdesc, &range, 1, cb,
+                                                   recover_data);
        }
 
        /* Uncompressed resource  */
@@ -626,7 +655,7 @@
        return read_partial_wim_resource(blob->rdesc,
                                         blob->offset_in_res + offset,
                                         size,
-                                        &cb);
+                                        &cb, false);
 }
 
 static int
@@ -643,15 +672,15 @@
                .func = noop_cb,
        };
        return read_partial_wim_resource(rdesc, 0,
-                                        rdesc->uncompressed_size, &cb);
+                                        rdesc->uncompressed_size, &cb, false);
 }
 
 static int
 read_wim_blob_prefix(const struct blob_descriptor *blob, u64 size,
-                    const struct consume_chunk_callback *cb)
+                    const struct consume_chunk_callback *cb, bool recover_data)
 {
        return read_partial_wim_resource(blob->rdesc, blob->offset_in_res,
-                                        size, cb);
+                                        size, cb, recover_data);
 }
 
 /* This function handles reading blob data that is located in an external file,
@@ -664,7 +693,8 @@
  * encrypted), so Windows uses its own code for its equivalent case.  */
 static int
 read_file_on_disk_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct consume_chunk_callback *cb)
+                        const struct consume_chunk_callback *cb,
+                        bool recover_data)
 {
        int ret;
        int raw_fd;
@@ -684,7 +714,8 @@
 #ifdef WITH_FUSE
 static int
 read_staging_file_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct consume_chunk_callback *cb)
+                        const struct consume_chunk_callback *cb,
+                        bool recover_data)
 {
        int raw_fd;
        struct filedes fd;
@@ -708,7 +739,8 @@
  * already located in an in-memory buffer.  */
 static int
 read_buffer_prefix(const struct blob_descriptor *blob,
-                  u64 size, const struct consume_chunk_callback *cb)
+                  u64 size, const struct consume_chunk_callback *cb,
+                  bool recover_data)
 {
        if (unlikely(!size))
                return 0;
@@ -717,7 +749,8 @@
 
 typedef int (*read_blob_prefix_handler_t)(const struct blob_descriptor *blob,
                                          u64 size,
-                                         const struct consume_chunk_callback 
*cb);
+                                         const struct consume_chunk_callback 
*cb,
+                                         bool recover_data);
 
 /*
  * Read the first @size bytes from a generic "blob", which may be located in 
any
@@ -728,11 +761,12 @@
  * Returns 0 on success; nonzero on error.  A nonzero value will be returned if
  * the blob data cannot be successfully read (for a number of different 
reasons,
  * depending on the blob location), or if @cb returned nonzero in which case
- * that error code will be returned.
+ * that error code will be returned.  If @recover_data is true, then errors
+ * decompressing chunks in WIM resources will be ignored.
  */
 static int
 read_blob_prefix(const struct blob_descriptor *blob, u64 size,
-                const struct consume_chunk_callback *cb)
+                const struct consume_chunk_callback *cb, bool recover_data)
 {
        static const read_blob_prefix_handler_t handlers[] = {
                [BLOB_IN_WIM] = read_wim_blob_prefix,
@@ -751,7 +785,7 @@
        wimlib_assert(blob->blob_location < ARRAY_LEN(handlers)
                      && handlers[blob->blob_location] != NULL);
        wimlib_assert(size <= blob->size);
-       return handlers[blob->blob_location](blob, size, cb);
+       return handlers[blob->blob_location](blob, size, cb, recover_data);
 }
 
 struct blob_chunk_ctx {
@@ -775,7 +809,7 @@
  * callbacks (all of which are optional).  */
 int
 read_blob_with_cbs(struct blob_descriptor *blob,
-                  const struct read_blob_callbacks *cbs)
+                  const struct read_blob_callbacks *cbs, bool recover_data)
 {
        int ret;
        struct blob_chunk_ctx ctx = {
@@ -792,7 +826,7 @@
        if (unlikely(ret))
                return ret;
 
-       ret = read_blob_prefix(blob, blob->size, &cb);
+       ret = read_blob_prefix(blob, blob->size, &cb, recover_data);
 
        return call_end_blob(blob, ret, cbs);
 }
@@ -807,7 +841,7 @@
                .func   = bufferer_cb,
                .ctx    = &buf,
        };
-       return read_blob_prefix(blob, blob->size, &cb);
+       return read_blob_prefix(blob, blob->size, &cb, false);
 }
 
 /* Retrieve the full uncompressed data of the specified blob.  A buffer large
@@ -955,6 +989,7 @@
        struct hasher_context *ctx = _ctx;
 
        sha1_init(&ctx->sha_ctx);
+       blob->corrupted = 0;
 
        return call_begin_blob(blob, &ctx->cbs);
 }
@@ -977,8 +1012,8 @@
 }
 
 static int
-report_sha1_mismatch_error(const struct blob_descriptor *blob,
-                          const u8 actual_hash[SHA1_HASH_SIZE])
+report_sha1_mismatch(struct blob_descriptor *blob,
+                    const u8 actual_hash[SHA1_HASH_SIZE], bool recover_data)
 {
        tchar expected_hashstr[SHA1_HASH_SIZE * 2 + 1];
        tchar actual_hashstr[SHA1_HASH_SIZE * 2 + 1];
@@ -989,6 +1024,8 @@
        sprint_hash(blob->hash, expected_hashstr);
        sprint_hash(actual_hash, actual_hashstr);
 
+       blob->corrupted = 1;
+
        if (blob_is_in_file(blob)) {
                ERROR("A file was concurrently modified!\n"
                      "        Path: \"%"TS"\"\n"
@@ -997,18 +1034,21 @@
                      blob_file_path(blob), expected_hashstr, actual_hashstr);
                return WIMLIB_ERR_CONCURRENT_MODIFICATION_DETECTED;
        } else if (blob->blob_location == BLOB_IN_WIM) {
+       #ifdef ENABLE_ERROR_MESSAGES
                const struct wim_resource_descriptor *rdesc = blob->rdesc;
-               ERROR("A WIM resource is corrupted!\n"
-                     "        WIM file: \"%"TS"\"\n"
-                     "        Blob uncompressed size: %"PRIu64"\n"
-                     "        Resource offset in WIM: %"PRIu64"\n"
-                     "        Resource uncompressed size: %"PRIu64"\n"
-                     "        Resource size in WIM: %"PRIu64"\n"
-                     "        Resource flags: 0x%x%"TS"\n"
-                     "        Resource compression type: %"TS"\n"
-                     "        Resource compression chunk size: %"PRIu32"\n"
-                     "        Expected SHA-1: %"TS"\n"
-                     "        Actual SHA-1: %"TS"\n",
+
+               (recover_data ? wimlib_warning : wimlib_error)(
+                     T("A WIM resource is corrupted!\n"
+                       "        WIM file: \"%"TS"\"\n"
+                       "        Blob uncompressed size: %"PRIu64"\n"
+                       "        Resource offset in WIM: %"PRIu64"\n"
+                       "        Resource uncompressed size: %"PRIu64"\n"
+                       "        Resource size in WIM: %"PRIu64"\n"
+                       "        Resource flags: 0x%x%"TS"\n"
+                       "        Resource compression type: %"TS"\n"
+                       "        Resource compression chunk size: %"PRIu32"\n"
+                       "        Expected SHA-1: %"TS"\n"
+                       "        Actual SHA-1: %"TS"\n"),
                      rdesc->wim->filename,
                      blob->size,
                      rdesc->offset_in_wim,
@@ -1020,6 +1060,9 @@
                                                rdesc->compression_type),
                      rdesc->chunk_size,
                      expected_hashstr, actual_hashstr);
+       #endif /* ENABLE_ERROR_MESSAGES */
+               if (recover_data)
+                       return 0;
                return WIMLIB_ERR_INVALID_RESOURCE_HASH;
        } else {
                ERROR("File data was concurrently modified!\n"
@@ -1058,7 +1101,8 @@
        } else if ((ctx->flags & VERIFY_BLOB_HASHES) &&
                   unlikely(!hashes_equal(hash, blob->hash)))
        {
-               ret = report_sha1_mismatch_error(blob, hash);
+               ret = report_sha1_mismatch(blob, hash,
+                                          ctx->flags & RECOVER_DATA);
                goto out_next_cb;
        }
        ret = 0;
@@ -1071,10 +1115,11 @@
  * SHA-1 message digest of the blob.  */
 int
 read_blob_with_sha1(struct blob_descriptor *blob,
-                   const struct read_blob_callbacks *cbs)
+                   const struct read_blob_callbacks *cbs, bool recover_data)
 {
        struct hasher_context hasher_ctx = {
-               .flags = VERIFY_BLOB_HASHES | COMPUTE_MISSING_BLOB_HASHES,
+               .flags = VERIFY_BLOB_HASHES | COMPUTE_MISSING_BLOB_HASHES |
+                        (recover_data ? RECOVER_DATA : 0),
                .cbs = *cbs,
        };
        struct read_blob_callbacks hasher_cbs = {
@@ -1083,7 +1128,7 @@
                .end_blob       = hasher_end_blob,
                .ctx            = &hasher_ctx,
        };
-       return read_blob_with_cbs(blob, &hasher_cbs);
+       return read_blob_with_cbs(blob, &hasher_cbs, recover_data);
 }
 
 static int
@@ -1091,7 +1136,8 @@
                             struct blob_descriptor *last_blob,
                             size_t blob_count,
                             size_t list_head_offset,
-                            const struct read_blob_callbacks *sink_cbs)
+                            const struct read_blob_callbacks *sink_cbs,
+                            bool recover_data)
 {
        struct data_range *ranges;
        bool ranges_malloced;
@@ -1141,7 +1187,7 @@
        };
 
        ret = read_compressed_wim_resource(first_blob->rdesc, ranges,
-                                          blob_count, &cb);
+                                          blob_count, &cb, recover_data);
 
        if (ranges_malloced)
                FREE(ranges);
@@ -1178,7 +1224,8 @@
  *             For all blobs being read that have already had SHA-1 message
  *             digests computed, calculate the SHA-1 message digest of the read
  *             data and compare it with the previously computed value.  If they
- *             do not match, return WIMLIB_ERR_INVALID_RESOURCE_HASH.
+ *             do not match, return WIMLIB_ERR_INVALID_RESOURCE_HASH (unless
+ *             RECOVER_DATA is also set, in which case just issue a warning).
  *
  *     COMPUTE_MISSING_BLOB_HASHES
  *             For all blobs being read that have not yet had their SHA-1
@@ -1188,6 +1235,9 @@
  *     BLOB_LIST_ALREADY_SORTED
  *             @blob_list is already sorted in sequential order for reading.
  *
+ *     RECOVER_DATA
+ *             Don't consider corrupted blob data to be an error.
+ *
  * The callback functions are allowed to delete the current blob from the list
  * if necessary.
  *
@@ -1273,14 +1323,15 @@
                                ret = read_blobs_in_solid_resource(blob, 
blob_last,
                                                                   blob_count,
                                                                   
list_head_offset,
-                                                                  sink_cbs);
+                                                                  sink_cbs,
+                                                                  flags & 
RECOVER_DATA);
                                if (ret)
                                        return ret;
                                continue;
                        }
                }
 
-               ret = read_blob_with_cbs(blob, sink_cbs);
+               ret = read_blob_with_cbs(blob, sink_cbs, flags & RECOVER_DATA);
                if (unlikely(ret && ret != BEGIN_BLOB_STATUS_SKIP_BLOB))
                        return ret;
        }
@@ -1314,19 +1365,20 @@
                .func   = extract_chunk_to_fd,
                .ctx    = fd,
        };
-       return read_blob_prefix(blob, size, &cb);
+       return read_blob_prefix(blob, size, &cb, false);
 }
 
 /* Extract the full uncompressed contents of the specified blob to the 
specified
  * file descriptor.  This checks the SHA-1 message digest.  */
 int
-extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd)
+extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd,
+                  bool recover_data)
 {
        struct read_blob_callbacks cbs = {
                .continue_blob  = extract_blob_chunk_to_fd,
                .ctx            = fd,
        };
-       return read_blob_with_sha1(blob, &cbs);
+       return read_blob_with_sha1(blob, &cbs, recover_data);
 }
 
 /* Calculate the SHA-1 message digest of a blob and store it in @blob->hash.  
*/
@@ -1335,7 +1387,7 @@
 {
        static const struct read_blob_callbacks cbs = {
        };
-       return read_blob_with_sha1(blob, &cbs);
+       return read_blob_with_sha1(blob, &cbs, false);
 }
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/src/split.c new/wimlib-1.13.4/src/split.c
--- old/wimlib-1.13.3/src/split.c       2018-05-02 05:38:31.000000000 +0200
+++ new/wimlib-1.13.4/src/split.c       2021-04-02 05:59:52.000000000 +0200
@@ -96,7 +96,6 @@
 
        for (part_number = 1; part_number <= swm_info->num_parts; 
part_number++) {
                int part_write_flags;
-               wimlib_progress_func_t progfunc;
 
                if (part_number != 1) {
                        tsprintf(swm_name_buf + swm_base_name_len,
@@ -118,8 +117,6 @@
                if (part_number != 1)
                        part_write_flags |= WIMLIB_WRITE_FLAG_NO_METADATA;
 
-               progfunc = orig_wim->progfunc;
-               orig_wim->progfunc = NULL;
                ret = write_wim_part(orig_wim,
                                     progress.split.part_name,
                                     WIMLIB_ALL_IMAGES,
@@ -129,7 +126,6 @@
                                     swm_info->num_parts,
                                     &swm_info->parts[part_number - 
1].blob_list,
                                     guid);
-               orig_wim->progfunc = progfunc;
                if (ret)
                        return ret;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/src/win32_capture.c new/wimlib-1.13.4/src/win32_capture.c
--- old/wimlib-1.13.3/src/win32_capture.c       2020-06-02 06:10:11.000000000 
+0200
+++ new/wimlib-1.13.4/src/win32_capture.c       2021-04-06 21:48:32.000000000 
+0200
@@ -488,7 +488,8 @@
  * described by @blob.  */
 int
 read_windows_file_prefix(const struct blob_descriptor *blob, u64 size,
-                        const struct consume_chunk_callback *cb)
+                        const struct consume_chunk_callback *cb,
+                        bool recover_data)
 {
        const struct windows_file *file = blob->windows_file;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/src/write.c new/wimlib-1.13.4/src/write.c
--- old/wimlib-1.13.3/src/write.c       2019-04-14 06:58:03.000000000 +0200
+++ new/wimlib-1.13.4/src/write.c       2021-04-19 06:35:01.000000000 +0200
@@ -301,7 +301,8 @@
 
 static int
 do_write_blobs_progress(struct write_blobs_progress_data *progress_data,
-                       u64 complete_size, u32 complete_count, bool discarded)
+                       u64 complete_size, u64 complete_compressed_size,
+                       u32 complete_count, bool discarded)
 {
        union wimlib_progress_info *progress = &progress_data->progress;
        int ret;
@@ -316,6 +317,8 @@
                }
        } else {
                progress->write_streams.completed_bytes += complete_size;
+               progress->write_streams.completed_compressed_bytes +=
+                       complete_compressed_size;
                progress->write_streams.completed_streams += complete_count;
        }
 
@@ -713,7 +716,9 @@
                                 * output reference count to the duplicate blob
                                 * in the former case.  */
                                ret = 
do_write_blobs_progress(&ctx->progress_data,
-                                                             blob->size, 1, 
true);
+                                                             blob->size,
+                                                             blob->size,
+                                                             1, true);
                                list_del(&blob->write_blobs_list);
                                list_del(&blob->blob_table_list);
                                if (new_blob->will_be_in_output_wim)
@@ -762,7 +767,7 @@
        if (filedes_seek(out_fd, begin_offset) == -1)
                return 0;
 
-       ret = extract_blob_to_fd(blob, out_fd);
+       ret = extract_blob_to_fd(blob, out_fd, false);
        if (ret) {
                /* Error reading the uncompressed data.  */
                if (out_fd->offset == begin_offset &&
@@ -867,8 +872,7 @@
 {
        int ret;
        struct blob_descriptor *blob;
-       u32 completed_blob_count;
-       u32 completed_size;
+       u32 completed_blob_count = 0;
 
        blob = list_entry(ctx->blobs_being_compressed.next,
                          struct blob_descriptor, write_blobs_list);
@@ -915,8 +919,6 @@
 
        ctx->cur_write_blob_offset += usize;
 
-       completed_size = usize;
-       completed_blob_count = 0;
        if (ctx->write_resource_flags & WRITE_RESOURCE_FLAG_SOLID) {
                /* Wrote chunk in solid mode.  It may have finished multiple
                 * blobs.  */
@@ -973,7 +975,7 @@
                }
        }
 
-       return do_write_blobs_progress(&ctx->progress_data, completed_size,
+       return do_write_blobs_progress(&ctx->progress_data, usize, csize,
                                       completed_blob_count, false);
 
 write_error:
@@ -1287,15 +1289,18 @@
                blob->rdesc->raw_copy_ok = 1;
 
        list_for_each_entry(blob, raw_copy_blobs, write_blobs_list) {
+               u64 compressed_size = 0;
+
                if (blob->rdesc->raw_copy_ok) {
                        /* Write each solid resource only one time.  */
                        ret = write_raw_copy_resource(blob->rdesc, out_fd);
                        if (ret)
                                return ret;
                        blob->rdesc->raw_copy_ok = 0;
+                       compressed_size = blob->rdesc->size_in_wim;
                }
                ret = do_write_blobs_progress(progress_data, blob->size,
-                                             1, false);
+                                             compressed_size, 1, false);
                if (ret)
                        return ret;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/tests/test-imagex-capture_and_apply 
new/wimlib-1.13.4/tests/test-imagex-capture_and_apply
--- old/wimlib-1.13.3/tests/test-imagex-capture_and_apply       2018-07-21 
19:21:18.000000000 +0200
+++ new/wimlib-1.13.4/tests/test-imagex-capture_and_apply       2021-04-07 
05:46:27.000000000 +0200
@@ -142,6 +142,20 @@
 
 . $srcdir/tests/common_tests.sh
 
+# Test the data recovery mode
+__msg "Testing data recovery mode"
+for file in corrupted_file_1.wim corrupted_file_2.wim; do
+       rm -rf out.dir
+       wimapply $srcdir/tests/wims/$file 1 out.dir 2>/dev/null && \
+               error "Applying $file in default mode unexpectedly succeeded"
+       rm -rf out.dir
+       wimapply --recover-data $srcdir/tests/wims/$file 1 out.dir || \
+               error "Applying $file in data recovery mode unexpectedly failed"
+       if [ ! -e out.dir/file ]; then
+               error "Recovered file not found"
+       fi
+done
+
 # Make sure exclusion list works
 __msg "Testing default capture configuration file"
 touch in.dir/hiberfil.sys
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/wimlib-1.13.3/tests/wims/README new/wimlib-1.13.4/tests/wims/README
--- old/wimlib-1.13.3/tests/wims/README 1970-01-01 01:00:00.000000000 +0100
+++ new/wimlib-1.13.4/tests/wims/README 2021-04-07 06:21:48.000000000 +0200
@@ -0,0 +1,27 @@
+Some fun files:
+
+corrupted_file_1.wim:  This WIM contains a file whose SHA-1 digest doesn't 
match.
+
+corrupted_file_2.wim:  This WIM contains a file that fails to decompress.
+
+cyclic.wim:  This WIM has an image with a cyclic directory structure and 
should be
+detected as invalid.
+
+duplicate_names.wim:  This WIM has an image with multiple files with the same
+name in the same directory, and should be detected as invalid.
+
+dotdot.wim:  This WIM has an image with the path
+/../../../../../../../../../../../../../../../../etc/passwd, and should be
+detected as invalid.  (Fun fact: WIMGAPI is dumb and will extract .. files, and
+requires running with Admin rights, so given a malicious WIM file it will
+overwrite arbitrary files on the target drive.)
+
+longpaths.wim:  This WIM has an image with a path longer than MAX_PATH on 
Windows.
+This should still be extracted successfully.
+
+empty_dacl.wim:  This WIM has an image containing file with a security
+descriptor having an empty DACL.  This is valid and should be extracted
+successfully.
+
+linux_xattrs_old.wim: Includes Linux xattrs in old format
+(TAG_WIMLIB_LINUX_XATTRS)
Binary files old/wimlib-1.13.3/tests/wims/corrupted_file_1.wim and 
new/wimlib-1.13.4/tests/wims/corrupted_file_1.wim differ
Binary files old/wimlib-1.13.3/tests/wims/corrupted_file_2.wim and 
new/wimlib-1.13.4/tests/wims/corrupted_file_2.wim differ
Binary files old/wimlib-1.13.3/tests/wims/cyclic.wim and 
new/wimlib-1.13.4/tests/wims/cyclic.wim differ
Binary files old/wimlib-1.13.3/tests/wims/dotdot.wim and 
new/wimlib-1.13.4/tests/wims/dotdot.wim differ
Binary files old/wimlib-1.13.3/tests/wims/duplicate_names.wim and 
new/wimlib-1.13.4/tests/wims/duplicate_names.wim differ
Binary files old/wimlib-1.13.3/tests/wims/empty_dacl.wim and 
new/wimlib-1.13.4/tests/wims/empty_dacl.wim differ
Binary files old/wimlib-1.13.3/tests/wims/linux_xattrs_old.wim and 
new/wimlib-1.13.4/tests/wims/linux_xattrs_old.wim differ
Binary files old/wimlib-1.13.3/tests/wims/longpaths.wim and 
new/wimlib-1.13.4/tests/wims/longpaths.wim differ

Reply via email to