redhotpenguin / perl-Archive-Zip

Archive::Zip as seen at https://metacpan.org/pod/Archive::Zip
Other
15 stars 44 forks source link

writeToFileNamed() crashes without error and kills calling routine if addString used with data which still has the UTF-8 flag #92

Open angwe opened 3 years ago

angwe commented 3 years ago

I can't easily create test case, but here is the difference:

use Archive::Zip qw ( :ERROR_CODES );
my $zip = Archive::Zip->new();
my $stringWithUTF8Data = "é";
my $zipFileName = "test.zip";
my $inZip = $zip->addString($stringWithUTF8Data, "Filename.txt");
print "Added UTF8 data.\n";
$inZip->desiredCompressionLevel(0);
my $status = $zip->writeToFileNamed($zipFileName);
if($status == AZ_OK) {
  print "Done writing Zip file.\n";
} else {
  print "Couldn't write Zip file.\n";
}

You will see "Added UTF8 data." printed, but never anything else. No error will be written to anywhere. There should be a badly-formed test.zip file if the permissions allowed it to be created (zip -T test.zip will return errors), or at least our script was making a partial zip file.

use Archive::Zip qw ( :ERROR_CODES );
use Encode;
my $zip = Archive::Zip->new();
my $stringWithUTF8Data = "é";
my $zipFileName = "test.zip";
$stringWithUTF8Data = Encode::encode_utf8($stringWithUTF8Data);
my $inZip = $zip->addString($stringWithUTF8Data, "Filename.txt");
print "Added UTF8 data.\n";
$inZip->desiredCompressionLevel(0);
my $status = $zip->writeToFileNamed($zipFileName);
if($status == AZ_OK) {
  print "Done writing Zip file.\n";
} else {
  print "Couldn't write Zip file.\n";
}

You will see "Added UTF8 data." and either "Done" or "Coudn't" depending on if the file could actually be written.

The use of Encode::encode_utf8() here has the effect of stripping the Perl built-in utf8 flag off the data.

Please note, this is the data itself, not any of the file names or member names, so the $Archive::Zip::UNICODE variable is not relevant.

It's somewhat maddening that this happens only at the point where the code tries to write the file, not when the data is added to the archive and that no errors are thrown.

Perl 5.16 on RHEL 7, Archive::Zip 1.68.