Commit 763f4f83 authored by Jonas Witschel's avatar Jonas Witschel
Browse files

Do not fail on JAR archives containing invalid members with a .jar extension

_jar_normalize_member() in the JAR handler calls
File::StripNondeterminism::handlers::zip::normalize_member for every archive
member with a .jar extension. If the member is not a valid archive (e.g.
because it is just an empty file), this leads to a hard failure "Reading ZIP
archive failed" in the ZIP handler.

To solve this, extend normalize_member() in the ZIP file to detect the file
type if no $normalizer is explicitly specified. This uses
get_normalizer_for_file(), which looks at both the file extension and the
"file" command to detect the type more accurately. Therefore we need to
preserve the name of the extracted temporary file instead of just calling it
"member".

With this change in place, we can leave the normalizer for files with a .jar
extension unspecified in _jar_normalize_member(). This way if the file is not
an archive, it will get skipped by get_normalizer_for_file() and a warning will
be printed instead of a fatal error.
parent ba5a0ac2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ sub _jar_normalize_member($$) {
		$timestamp--;
	} elsif ($member->fileName() =~ /\.jar$/) {
		File::StripNondeterminism::handlers::zip::normalize_member($member,
			\&normalize);
			undef);
	}

	return $timestamp;
+8 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ package File::StripNondeterminism::handlers::zip;
use strict;
use warnings;

use File::Basename qw(basename);
use File::Temp;
use File::StripNondeterminism;
use Archive::Zip qw/:CONSTANTS :ERROR_CODES/;
@@ -65,13 +66,19 @@ sub normalize_member($$) {

	# Extract the member to a temporary file.
	my $tempdir = File::Temp->newdir();
	my $filename = "$tempdir/member";
	my $filename = "$tempdir/" . basename($member->fileName());
	my $original_size = $member->compressedSize();
	$member->extractToFileNamed($filename);
	chmod(0600, $filename);
	$member->{'compressedSize'} = $original_size
	  ; # Work around https://github.com/redhotpenguin/perl-Archive-Zip/issues/11

	$normalizer = File::StripNondeterminism::get_normalizer_for_file($filename) unless defined $normalizer;
	if (not defined $normalizer) {
		warn "strip-nondeterminism: unknown file type of " . $member->fileName();
		return;
	}

	# Normalize the temporary file.
	if ($normalizer->($filename)) {
		# Normalizer modified the temporary file.