Update IO-Compress to CPAN version 2.086
authorChris 'BinGOs' Williams <chris@bingosnet.co.uk>
Mon, 3 Jun 2019 12:07:59 +0000 (13:07 +0100)
committerChris 'BinGOs' Williams <chris@bingosnet.co.uk>
Mon, 3 Jun 2019 12:07:59 +0000 (13:07 +0100)
  [DELTA]

  2.086 31 March 2019

      * IO::Compress::Zip & IO::Uncompress::Unzip
        Added support for Language Encoding Flag via the EFS option.
        Starting point was pull request https://github.com/pmqs/IO-Compress/pull/1

      * zipdetails - some support for MVS (Z390) zip files

      * IO::Uncompress::Base
        Issue with trailing data after zip archive
        #128626 for IO-Compress: mainframe zip archive

      * t/cz-14gzopen.t
        cperl error found in http://www.cpantesters.org/cpan/report/448cafc4-3108-11e9-9b6b-d3d33d7b1231
        Perl has this: "Not enough arguments for Compress::Zlib::gzopen"
        cperl uses this: "Not enough arguments for subroutine entry Compress::Zlib::gzopen"

      * Handlers being called when optional modules are not installed
        #128538:  $SIG{__DIE__}

      *  #128194: Beef up diag when system returns error

      * Moved source to github https://github.com/pmqs/IO-Compress

      * Add META_MERGE to Makefile.PL

      * Added meta-json.t & meta-yaml.t

36 files changed:
MANIFEST
Porting/Maintainers.pl
cpan/IO-Compress/Makefile.PL
cpan/IO-Compress/bin/zipdetails
cpan/IO-Compress/lib/Compress/Zlib.pm
cpan/IO-Compress/lib/IO/Compress/Adapter/Bzip2.pm
cpan/IO-Compress/lib/IO/Compress/Adapter/Deflate.pm
cpan/IO-Compress/lib/IO/Compress/Adapter/Identity.pm
cpan/IO-Compress/lib/IO/Compress/Base.pm
cpan/IO-Compress/lib/IO/Compress/Base/Common.pm
cpan/IO-Compress/lib/IO/Compress/Bzip2.pm
cpan/IO-Compress/lib/IO/Compress/Deflate.pm
cpan/IO-Compress/lib/IO/Compress/Gzip.pm
cpan/IO-Compress/lib/IO/Compress/Gzip/Constants.pm
cpan/IO-Compress/lib/IO/Compress/RawDeflate.pm
cpan/IO-Compress/lib/IO/Compress/Zip.pm
cpan/IO-Compress/lib/IO/Compress/Zip/Constants.pm
cpan/IO-Compress/lib/IO/Compress/Zlib/Constants.pm
cpan/IO-Compress/lib/IO/Compress/Zlib/Extra.pm
cpan/IO-Compress/lib/IO/Uncompress/Adapter/Bunzip2.pm
cpan/IO-Compress/lib/IO/Uncompress/Adapter/Identity.pm
cpan/IO-Compress/lib/IO/Uncompress/Adapter/Inflate.pm
cpan/IO-Compress/lib/IO/Uncompress/AnyInflate.pm
cpan/IO-Compress/lib/IO/Uncompress/AnyUncompress.pm
cpan/IO-Compress/lib/IO/Uncompress/Base.pm
cpan/IO-Compress/lib/IO/Uncompress/Bunzip2.pm
cpan/IO-Compress/lib/IO/Uncompress/Gunzip.pm
cpan/IO-Compress/lib/IO/Uncompress/Inflate.pm
cpan/IO-Compress/lib/IO/Uncompress/RawInflate.pm
cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm
cpan/IO-Compress/t/000prereq.t
cpan/IO-Compress/t/050interop-gzip.t
cpan/IO-Compress/t/107multi-zip-only.t [new file with mode: 0644]
cpan/IO-Compress/t/112utf8-zip.t [new file with mode: 0644]
cpan/IO-Compress/t/cz-14gzopen.t
cpan/IO-Compress/t/files/bad-efs.zip [new file with mode: 0644]

index bb1e5a1..e5bdf66 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1099,6 +1099,7 @@ cpan/IO-Compress/t/107multi-deflate.t                     IO::Compress
 cpan/IO-Compress/t/107multi-gzip.t                     IO::Compress
 cpan/IO-Compress/t/107multi-rawdeflate.t               IO::Compress
 cpan/IO-Compress/t/107multi-zip.t                      IO::Compress
+cpan/IO-Compress/t/107multi-zip-only.t
 cpan/IO-Compress/t/108anyunc-bzip2.t                   IO::Compress
 cpan/IO-Compress/t/108anyunc-deflate.t                 IO::Compress
 cpan/IO-Compress/t/108anyunc-gzip.t                    IO::Compress
@@ -1115,6 +1116,7 @@ cpan/IO-Compress/t/110encode-gzip.t                       IO::Compress
 cpan/IO-Compress/t/110encode-rawdeflate.t              IO::Compress
 cpan/IO-Compress/t/110encode-zip.t                     IO::Compress
 cpan/IO-Compress/t/111const-deflate.t                  IO::Compress
+cpan/IO-Compress/t/112utf8-zip.t
 cpan/IO-Compress/t/999pod.t                            IO::Compress
 cpan/IO-Compress/t/compress/any.pl                     Compress::Zlib
 cpan/IO-Compress/t/compress/anyunc.pl                  Compress::Zlib
@@ -1135,6 +1137,7 @@ cpan/IO-Compress/t/cz-03zlib-v1.t                 IO::Compress
 cpan/IO-Compress/t/cz-06gzsetp.t                       IO::Compress
 cpan/IO-Compress/t/cz-08encoding.t                     IO::Compress
 cpan/IO-Compress/t/cz-14gzopen.t                       IO::Compress
+cpan/IO-Compress/t/files/bad-efs.zip
 cpan/IO-Compress/t/files/meta.xml
 cpan/IO-Compress/t/files/test.ods
 cpan/IO-Compress/t/globmapper.t                                IO::Compress
index d81c391..c3b817f 100755 (executable)
@@ -616,11 +616,12 @@ use File::Glob qw(:case);
     },
 
     'IO-Compress' => {
-        'DISTRIBUTION' => 'PMQS/IO-Compress-2.084.tar.gz',
+        'DISTRIBUTION' => 'PMQS/IO-Compress-2.086.tar.gz',
         'FILES'        => q[cpan/IO-Compress],
         'EXCLUDED'     => [
             qr{^examples/},
             qr{^t/Test/},
+            qr{^t/999meta-},
             't/010examples-bzip2.t',
             't/010examples-zlib.t',
             't/cz-05examples.t',
index ca8cce4..f716e08 100644 (file)
@@ -3,7 +3,7 @@
 use strict ;
 require 5.006 ;
 
-$::VERSION = '2.084' ;
+$::VERSION = '2.086' ;
 
 use lib '.';
 use private::MakeUtil;
@@ -50,11 +50,33 @@ WriteMakefile(
         : ()
     ),
 
-    META_MERGE => {
-        no_index => {
-            directory => [ 't', 'private' ],
-        },
-    },    
+     ( eval { ExtUtils::MakeMaker->VERSION(6.46) }  
+        ? ( META_MERGE  => {
+    
+                "meta-spec" => { version => 2 },
+
+                no_index => {
+                    directory => [ 't', 'private' ],
+                },
+
+                resources   => {
+                
+                    bugtracker  => {
+                        web     => 'https://github.com/pmqs/IO-Compress/issues'
+                    },
+
+                    homepage    => 'https://github.com/pmqs/IO-Compress',
+
+                    repository  => {
+                        type    => 'git',
+                        url     => 'git://github.com/pmqs/IO-Compress.git',
+                        web     => 'https://github.com/pmqs/IO-Compress',
+                    },        
+                },
+              } 
+            ) 
+        : ()
+    ),
 
     ((ExtUtils::MakeMaker->VERSION() gt '6.30') ?
         ('LICENSE'  => 'perl')         : ()),    
index ac647b3..d7b5146 100644 (file)
@@ -139,7 +139,7 @@ my %Extras = (
 
       # The Header ID mappings defined by Info-ZIP and third parties are:
 
-      0x0065,  ['IBM S/390 attributes - uncompressed', undef],
+      0x0065,  ['IBM S/390 attributes - uncompressed', \&decodeMVS],
       0x0066,  ['IBM S/390 attributes - compressed', undef],
       0x07c8,  ['Info-ZIP Macintosh (old, J. Lee)', undef],
       0x2605,  ['ZipIt Macintosh (first version)', undef],
@@ -180,7 +180,7 @@ my %Extras = (
 
        );
 
-my $VERSION = "1.09" ;
+my $VERSION = "1.10" ;
 
 my $FH;
 
@@ -1463,6 +1463,24 @@ sub decode_NT_security
     }
 }
 
+sub decodeMVS
+{
+    my $len = shift;
+    my $context = shift;
+
+    # data in Big-Endian
+    myRead(my $data, $len);
+    my $ID = unpack("N", $data);
+
+    if ($ID == 0xE9F3F9F0)
+    {
+        out($data, "  ID", "'Z390'");
+        substr($data, 0, 4) = '';
+    }
+
+    out($data, "  Extra Payload", hexDump($data));
+}
+
 sub printAes
 {
     my $context = shift ;
@@ -2062,7 +2080,7 @@ OPTIONS
      -h     display help
      -v     Verbose - output more stuff
     
-Copyright (c) 2011-2018 Paul Marquess. All rights reserved.
+Copyright (c) 2011-2019 Paul Marquess. All rights reserved.
 
 This program is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself.
@@ -2182,7 +2200,7 @@ Paul Marquess F<pmqs@cpan.org>.
 
 =head1 COPYRIGHT 
 
-Copyright (c) 2011-2018 Paul Marquess. All rights reserved.
+Copyright (c) 2011-2019 Paul Marquess. All rights reserved.
 
 This program is free software; you can redistribute it and/or modify it
 under the same terms as Perl itself. 
index ce79d7d..70396fe 100644 (file)
@@ -7,17 +7,17 @@ use Carp ;
 use IO::Handle ;
 use Scalar::Util qw(dualvar);
 
-use IO::Compress::Base::Common 2.084 ;
-use Compress::Raw::Zlib 2.084 ;
-use IO::Compress::Gzip 2.084 ;
-use IO::Uncompress::Gunzip 2.084 ;
+use IO::Compress::Base::Common 2.086 ;
+use Compress::Raw::Zlib 2.086 ;
+use IO::Compress::Gzip 2.086 ;
+use IO::Uncompress::Gunzip 2.086 ;
 
 use strict ;
 use warnings ;
 use bytes ;
 our ($VERSION, $XS_VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $XS_VERSION = $VERSION; 
 $VERSION = eval $VERSION;
 
@@ -224,7 +224,7 @@ sub Compress::Zlib::gzFile::gzseek
 
     my $gz = $self->[0] ;
     my $status ;
-    eval { $status = $gz->seek($offset, $whence) ; };
+    eval { local $SIG{__DIE__}; $status = $gz->seek($offset, $whence) ; };
     if ($@)
     {
         my $error = $@;
@@ -461,7 +461,7 @@ sub inflate
 
 package Compress::Zlib ;
 
-use IO::Compress::Gzip::Constants 2.084 ;
+use IO::Compress::Gzip::Constants 2.086 ;
 
 sub memGzip($)
 {
index 623a2c6..efc3e32 100644 (file)
@@ -4,12 +4,12 @@ use strict;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common  2.084 qw(:Status);
+use IO::Compress::Base::Common  2.086 qw(:Status);
 
-use Compress::Raw::Bzip2  2.084 ;
+use Compress::Raw::Bzip2  2.086 ;
 
 our ($VERSION);
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 sub mkCompObject
 {
index 8903287..d495e98 100644 (file)
@@ -4,13 +4,13 @@ use strict;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common 2.084 qw(:Status);
-use Compress::Raw::Zlib  2.084 qw( !crc32 !adler32 ) ;
+use IO::Compress::Base::Common 2.086 qw(:Status);
+use Compress::Raw::Zlib  2.086 qw( !crc32 !adler32 ) ;
                                   
 require Exporter;                                     
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, @EXPORT, %DEFLATE_CONSTANTS);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 @ISA = qw(Exporter);
 @EXPORT_OK = @Compress::Raw::Zlib::DEFLATE_CONSTANTS;
 %EXPORT_TAGS = %Compress::Raw::Zlib::DEFLATE_CONSTANTS;
index ae23102..7ff2ed5 100644 (file)
@@ -4,10 +4,10 @@ use strict;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common  2.084 qw(:Status);
+use IO::Compress::Base::Common  2.086 qw(:Status);
 our ($VERSION);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 sub mkCompObject
 {
index 1e2a54b..0981a10 100644 (file)
@@ -6,7 +6,7 @@ require 5.006 ;
 use strict ;
 use warnings;
 
-use IO::Compress::Base::Common 2.084 ;
+use IO::Compress::Base::Common 2.086 ;
 
 use IO::File (); ;
 use Scalar::Util ();
@@ -20,7 +20,7 @@ use Symbol();
 our (@ISA, $VERSION);
 @ISA    = qw(IO::File Exporter);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 #Can't locate object method "SWASHNEW" via package "utf8" (perhaps you forgot to load "utf8"?) at .../ext/Compress-Zlib/Gzip/blib/lib/Compress/Zlib/Common.pm line 16.
 
index 5323289..2dfa70e 100644 (file)
@@ -11,7 +11,7 @@ use File::GlobMapper;
 require Exporter;
 our ($VERSION, @ISA, @EXPORT, %EXPORT_TAGS, $HAS_ENCODE);
 @ISA = qw(Exporter);
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 @EXPORT = qw( isaFilehandle isaFilename isaScalar
               whatIsInput whatIsOutput
index 1c0d027..fd5f25f 100644 (file)
@@ -5,16 +5,16 @@ use warnings;
 use bytes;
 require Exporter ;
 
-use IO::Compress::Base 2.084 ;
+use IO::Compress::Base 2.086 ;
 
-use IO::Compress::Base::Common  2.084 qw();
-use IO::Compress::Adapter::Bzip2 2.084 ;
+use IO::Compress::Base::Common  2.086 qw();
+use IO::Compress::Adapter::Bzip2 2.086 ;
 
 
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $Bzip2Error);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $Bzip2Error = '';
 
 @ISA    = qw(IO::Compress::Base Exporter);
@@ -51,7 +51,7 @@ sub getExtraParams
 {
     my $self = shift ;
 
-    use IO::Compress::Base::Common  2.084 qw(:Parse);
+    use IO::Compress::Base::Common  2.086 qw(:Parse);
     
     return (  
             'blocksize100k' => [IO::Compress::Base::Common::Parse_unsigned,  1],
index 1ca86c9..029a60a 100644 (file)
@@ -8,16 +8,16 @@ use bytes;
 
 require Exporter ;
 
-use IO::Compress::RawDeflate 2.084 ();
-use IO::Compress::Adapter::Deflate 2.084 ;
+use IO::Compress::RawDeflate 2.086 ();
+use IO::Compress::Adapter::Deflate 2.086 ;
 
-use IO::Compress::Zlib::Constants 2.084 ;
-use IO::Compress::Base::Common  2.084 qw();
+use IO::Compress::Zlib::Constants 2.086 ;
+use IO::Compress::Base::Common  2.086 qw();
 
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $DeflateError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $DeflateError = '';
 
 @ISA    = qw(IO::Compress::RawDeflate Exporter);
index 5302011..bdb218c 100644 (file)
@@ -8,12 +8,12 @@ use bytes;
 
 require Exporter ;
 
-use IO::Compress::RawDeflate 2.084 () ; 
-use IO::Compress::Adapter::Deflate 2.084 ;
+use IO::Compress::RawDeflate 2.086 () ; 
+use IO::Compress::Adapter::Deflate 2.086 ;
 
-use IO::Compress::Base::Common  2.084 qw(:Status );
-use IO::Compress::Gzip::Constants 2.084 ;
-use IO::Compress::Zlib::Extra 2.084 ;
+use IO::Compress::Base::Common  2.086 qw(:Status );
+use IO::Compress::Gzip::Constants 2.086 ;
+use IO::Compress::Zlib::Extra 2.086 ;
 
 BEGIN
 {
@@ -25,7 +25,7 @@ BEGIN
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $GzipError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $GzipError = '' ;
 
 @ISA    = qw(IO::Compress::RawDeflate Exporter);
index d1bd0c2..aad288e 100644 (file)
@@ -9,7 +9,7 @@ require Exporter;
 our ($VERSION, @ISA, @EXPORT, %GZIP_OS_Names);
 our ($GZIP_FNAME_INVALID_CHAR_RE, $GZIP_FCOMMENT_INVALID_CHAR_RE);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 @ISA = qw(Exporter);
 
index b2f38ff..73d3c1c 100644 (file)
@@ -6,15 +6,15 @@ use strict ;
 use warnings;
 use bytes;
 
-use IO::Compress::Base 2.084 ;
-use IO::Compress::Base::Common  2.084 qw(:Status );
-use IO::Compress::Adapter::Deflate 2.084 ;
+use IO::Compress::Base 2.086 ;
+use IO::Compress::Base::Common  2.086 qw(:Status );
+use IO::Compress::Adapter::Deflate 2.086 ;
 
 require Exporter ;
 
 our ($VERSION, @ISA, @EXPORT_OK, %DEFLATE_CONSTANTS, %EXPORT_TAGS, $RawDeflateError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $RawDeflateError = '';
 
 @ISA = qw(IO::Compress::Base Exporter);
@@ -116,8 +116,8 @@ sub getExtraParams
     return getZlibParams();
 }
 
-use IO::Compress::Base::Common  2.084 qw(:Parse);
-use Compress::Raw::Zlib  2.084 qw(Z_DEFLATED Z_DEFAULT_COMPRESSION Z_DEFAULT_STRATEGY);
+use IO::Compress::Base::Common  2.086 qw(:Parse);
+use Compress::Raw::Zlib  2.086 qw(Z_DEFLATED Z_DEFAULT_COMPRESSION Z_DEFAULT_STRATEGY);
 our %PARAMS = (
             #'method'   => [IO::Compress::Base::Common::Parse_unsigned,  Z_DEFLATED],
             'level'     => [IO::Compress::Base::Common::Parse_signed,    Z_DEFAULT_COMPRESSION],
index eabeef6..f30f45c 100644 (file)
@@ -4,30 +4,30 @@ use strict ;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common  2.084 qw(:Status );
-use IO::Compress::RawDeflate 2.084 ();
-use IO::Compress::Adapter::Deflate 2.084 ;
-use IO::Compress::Adapter::Identity 2.084 ;
-use IO::Compress::Zlib::Extra 2.084 ;
-use IO::Compress::Zip::Constants 2.084 ;
+use IO::Compress::Base::Common  2.086 qw(:Status );
+use IO::Compress::RawDeflate 2.086 ();
+use IO::Compress::Adapter::Deflate 2.086 ;
+use IO::Compress::Adapter::Identity 2.086 ;
+use IO::Compress::Zlib::Extra 2.086 ;
+use IO::Compress::Zip::Constants 2.086 ;
 
 use File::Spec();
 use Config;
 
-use Compress::Raw::Zlib  2.084 (); 
+use Compress::Raw::Zlib  2.086 (); 
 
 BEGIN
 {
     eval { require IO::Compress::Adapter::Bzip2 ; 
-           import  IO::Compress::Adapter::Bzip2 2.084 ; 
+           import  IO::Compress::Adapter::Bzip2 2.086 ; 
            require IO::Compress::Bzip2 ; 
-           import  IO::Compress::Bzip2 2.084 ; 
+           import  IO::Compress::Bzip2 2.086 ; 
          } ;
          
     eval { require IO::Compress::Adapter::Lzma ; 
-           import  IO::Compress::Adapter::Lzma 2.084 ; 
+           import  IO::Compress::Adapter::Lzma 2.086 ; 
            require IO::Compress::Lzma ; 
-           import  IO::Compress::Lzma 2.084 ; 
+           import  IO::Compress::Lzma 2.086 ; 
          } ;
 }
 
@@ -36,7 +36,7 @@ require Exporter ;
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $ZipError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $ZipError = '';
 
 @ISA = qw(IO::Compress::RawDeflate Exporter);
@@ -246,13 +246,17 @@ sub mkHeader
         &{ *$self->{ZipData}{FilterName} }() ;
     }
 
-#    if ( $param->getValue('utf8') ) {
-#        require Encode ;
-#        $filename = Encode::encode_utf8($filename)
-#            if length $filename ;
-#        $comment = Encode::encode_utf8($comment)
-#            if length $comment ;
-#    }
+   if ( $param->getValue('efs') && $] >= 5.008004) {
+        if (length $filename) {
+            utf8::downgrade($filename, 1)
+                or Carp::croak "Wide character in zip filename";
+        }
+
+        if (length $comment) {
+            utf8::downgrade($comment, 1)
+                or Carp::croak "Wide character in zip comment";
+        }
+   }   
 
     my $hdr = '';
 
@@ -325,8 +329,8 @@ sub mkHeader
     $gpFlag |= ZIP_GP_FLAG_LZMA_EOS_PRESENT
         if $method == ZIP_CM_LZMA ;
 
-#    $gpFlag |= ZIP_GP_FLAG_LANGUAGE_ENCODING
-#        if  $param->getValue('utf8') && (length($filename) || length($comment));
+    $gpFlag |= ZIP_GP_FLAG_LANGUAGE_ENCODING
+        if  $param->getValue('efs') && (length($filename) || length($comment));
 
     my $version = $ZIP_CM_MIN_VERSIONS{$method};
     $version = ZIP64_MIN_VERSION
@@ -682,7 +686,7 @@ our %PARAMS = (
             'name'      => [IO::Compress::Base::Common::Parse_any,       ''],
             'filtername'=> [IO::Compress::Base::Common::Parse_code,      undef],
             'canonicalname'=> [IO::Compress::Base::Common::Parse_boolean,   0],
-#            'utf8'      => [IO::Compress::Base::Common::Parse_boolean,   0],
+            'efs'       => [IO::Compress::Base::Common::Parse_boolean,   0],
             'time'      => [IO::Compress::Base::Common::Parse_any,       undef],
             'extime'    => [IO::Compress::Base::Common::Parse_any,       undef],
             'exunix2'   => [IO::Compress::Base::Common::Parse_any,       undef], 
@@ -1291,6 +1295,9 @@ no zip filename field will be created.
 Note that both the C<CanonicalName> and C<FilterName> options
 can modify the value used for the zip filename header field.
 
+Also note that you should set the C<Efs> option to true if you are working
+with UTF8 filenames. 
+
 =item C<< CanonicalName => 0|1 >>
 
 This option controls whether the filename field in the zip header is
@@ -1343,6 +1350,19 @@ filenames before they are stored in C<$zipfile>.
             FilterName => sub { s[^$dir/][] } ;
     }
 
+=item C<< Efs => 0|1 >>
+
+This option controls setting of the "Language Encoding Flag" (EFS) in the zip
+archive. When set, the filename and comment fields for the zip archive MUST
+be valid UTF-8. 
+
+If the string used for the filename and/or comment is not valid UTF-8 when this option
+is true, the script will die with a "wide character" error.
+
+Note that this option only works with Perl 5.8.4 or better.
+
+This option defaults to B<false>.
+
 =item C<< Time => $number >>
 
 Sets the last modified time field in the zip header to $number.
@@ -1424,6 +1444,8 @@ By default no UnixN extra field is created.
 Stores the contents of C<$comment> in the Central File Header of
 the zip file.
 
+Set the C<Efs> option to true if you want to store a UTF8 comment.
+
 By default, no comment field is written to the zip file.
 
 =item C<< ZipComment => $comment >>
index d28a6ae..b087ff1 100644 (file)
@@ -7,7 +7,7 @@ require Exporter;
 
 our ($VERSION, @ISA, @EXPORT, %ZIP_CM_MIN_VERSIONS);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 @ISA = qw(Exporter);
 
index d0d053b..a7190c2 100644 (file)
@@ -9,7 +9,7 @@ require Exporter;
 
 our ($VERSION, @ISA, @EXPORT);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 @ISA = qw(Exporter);
 
index a88adba..bfe0aca 100644 (file)
@@ -8,9 +8,9 @@ use bytes;
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
-use IO::Compress::Gzip::Constants 2.084 ;
+use IO::Compress::Gzip::Constants 2.086 ;
 
 sub ExtraFieldError
 {
index 1aa9a8c..79cd989 100644 (file)
@@ -4,12 +4,12 @@ use strict;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common 2.084 qw(:Status);
+use IO::Compress::Base::Common 2.086 qw(:Status);
 
-use Compress::Raw::Bzip2 2.084 ;
+use Compress::Raw::Bzip2 2.086 ;
 
 our ($VERSION, @ISA);
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 sub mkUncompObject
 {
index 5601599..443cf8d 100644 (file)
@@ -4,14 +4,14 @@ use warnings;
 use strict;
 use bytes;
 
-use IO::Compress::Base::Common  2.084 qw(:Status);
+use IO::Compress::Base::Common  2.086 qw(:Status);
 use IO::Compress::Zip::Constants ;
 
 our ($VERSION);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
-use Compress::Raw::Zlib  2.084 ();
+use Compress::Raw::Zlib  2.086 ();
 
 sub mkUncompObject
 {
index f51c64d..afbad07 100644 (file)
@@ -4,11 +4,11 @@ use strict;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common  2.084 qw(:Status);
-use Compress::Raw::Zlib  2.084 qw(Z_OK Z_BUF_ERROR Z_STREAM_END Z_FINISH MAX_WBITS);
+use IO::Compress::Base::Common  2.086 qw(:Status);
+use Compress::Raw::Zlib  2.086 qw(Z_OK Z_BUF_ERROR Z_STREAM_END Z_FINISH MAX_WBITS);
 
 our ($VERSION);
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 
 
index be46488..cb04b1e 100644 (file)
@@ -6,22 +6,22 @@ use strict;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common  2.084 ();
+use IO::Compress::Base::Common  2.086 ();
 
-use IO::Uncompress::Adapter::Inflate  2.084 ();
+use IO::Uncompress::Adapter::Inflate  2.086 ();
 
 
-use IO::Uncompress::Base  2.084 ;
-use IO::Uncompress::Gunzip  2.084 ;
-use IO::Uncompress::Inflate  2.084 ;
-use IO::Uncompress::RawInflate  2.084 ;
-use IO::Uncompress::Unzip  2.084 ;
+use IO::Uncompress::Base  2.086 ;
+use IO::Uncompress::Gunzip  2.086 ;
+use IO::Uncompress::Inflate  2.086 ;
+use IO::Uncompress::RawInflate  2.086 ;
+use IO::Uncompress::Unzip  2.086 ;
 
 require Exporter ;
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyInflateError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $AnyInflateError = '';
 
 @ISA = qw(IO::Uncompress::Base Exporter);
@@ -48,7 +48,7 @@ sub anyinflate
 
 sub getExtraParams
 {
-    use IO::Compress::Base::Common  2.084 qw(:Parse);
+    use IO::Compress::Base::Common  2.086 qw(:Parse);
     return ( 'rawinflate' => [Parse_boolean,  0] ) ;
 }
 
index c6dfce5..69e8085 100644 (file)
@@ -4,16 +4,16 @@ use strict;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common 2.084 ();
+use IO::Compress::Base::Common 2.086 ();
 
-use IO::Uncompress::Base 2.084 ;
+use IO::Uncompress::Base 2.086 ;
 
 
 require Exporter ;
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyUncompressError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $AnyUncompressError = '';
 
 @ISA = qw(IO::Uncompress::Base Exporter);
@@ -29,26 +29,30 @@ BEGIN
 {
    local @INC = @INC;
    pop @INC if $INC[-1] eq '.';
-   eval ' use IO::Uncompress::Adapter::Inflate 2.084 ;';
-   eval ' use IO::Uncompress::Adapter::Bunzip2 2.084 ;';
-   eval ' use IO::Uncompress::Adapter::LZO 2.084 ;';
-   eval ' use IO::Uncompress::Adapter::Lzf 2.084 ;';
-   eval ' use IO::Uncompress::Adapter::UnLzma 2.084 ;';
-   eval ' use IO::Uncompress::Adapter::UnXz 2.084 ;';
+
+   # Don't trigger any __DIE__ Hooks.
+   local $SIG{__DIE__};
+
+   eval ' use IO::Uncompress::Adapter::Inflate 2.086 ;';
+   eval ' use IO::Uncompress::Adapter::Bunzip2 2.086 ;';
+   eval ' use IO::Uncompress::Adapter::LZO 2.086 ;';
+   eval ' use IO::Uncompress::Adapter::Lzf 2.086 ;';
+   eval ' use IO::Uncompress::Adapter::UnLzma 2.086 ;';
+   eval ' use IO::Uncompress::Adapter::UnXz 2.086 ;';
    eval ' use IO::Uncompress::Adapter::UnZstd 2.083 ;';
-   eval ' use IO::Uncompress::Adapter::UnLzip 2.084 ;';
-
-   eval ' use IO::Uncompress::Bunzip2 2.084 ;';
-   eval ' use IO::Uncompress::UnLzop 2.084 ;';
-   eval ' use IO::Uncompress::Gunzip 2.084 ;';
-   eval ' use IO::Uncompress::Inflate 2.084 ;';
-   eval ' use IO::Uncompress::RawInflate 2.084 ;';
-   eval ' use IO::Uncompress::Unzip 2.084 ;';
-   eval ' use IO::Uncompress::UnLzf 2.084 ;';
-   eval ' use IO::Uncompress::UnLzma 2.084 ;';
-   eval ' use IO::Uncompress::UnXz 2.084 ;';
-   eval ' use IO::Uncompress::UnZstd 2.084 ;';
-   eval ' use IO::Uncompress::UnLzip 2.084 ;';
+   eval ' use IO::Uncompress::Adapter::UnLzip 2.086 ;';
+
+   eval ' use IO::Uncompress::Bunzip2 2.086 ;';
+   eval ' use IO::Uncompress::UnLzop 2.086 ;';
+   eval ' use IO::Uncompress::Gunzip 2.086 ;';
+   eval ' use IO::Uncompress::Inflate 2.086 ;';
+   eval ' use IO::Uncompress::RawInflate 2.086 ;';
+   eval ' use IO::Uncompress::Unzip 2.086 ;';
+   eval ' use IO::Uncompress::UnLzf 2.086 ;';
+   eval ' use IO::Uncompress::UnLzma 2.086 ;';
+   eval ' use IO::Uncompress::UnXz 2.086 ;';
+   eval ' use IO::Uncompress::UnZstd 2.086 ;';
+   eval ' use IO::Uncompress::UnLzip 2.086 ;';
 
 }
 
index 06fb04a..8fd00f8 100644 (file)
@@ -9,12 +9,12 @@ our (@ISA, $VERSION, @EXPORT_OK, %EXPORT_TAGS);
 @ISA    = qw(IO::File Exporter);
 
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 use constant G_EOF => 0 ;
 use constant G_ERR => -1 ;
 
-use IO::Compress::Base::Common 2.084 ;
+use IO::Compress::Base::Common 2.086 ;
 
 use IO::File ;
 use Symbol;
@@ -1050,6 +1050,10 @@ sub gotoNextStream
             return 0;
         }
 
+        # Not EOF, so Transparent mode kicks in now for trailing data
+        # Reset member name in case anyone calls getHeaderInfo()->{Name}
+        *$self->{Info} = { Name => undef, Type  => 'plain' };
+
         $self->clearError();
         *$self->{Type} = 'plain';
         *$self->{Plain} = 1;
index 7a84bcd..427b98f 100644 (file)
@@ -4,15 +4,15 @@ use strict ;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common 2.084 qw(:Status );
+use IO::Compress::Base::Common 2.086 qw(:Status );
 
-use IO::Uncompress::Base 2.084 ;
-use IO::Uncompress::Adapter::Bunzip2 2.084 ;
+use IO::Uncompress::Base 2.086 ;
+use IO::Uncompress::Adapter::Bunzip2 2.086 ;
 
 require Exporter ;
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $Bunzip2Error);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $Bunzip2Error = '';
 
 @ISA    = qw(IO::Uncompress::Base Exporter);
index 46dd108..1ca0456 100644 (file)
@@ -9,12 +9,12 @@ use strict ;
 use warnings;
 use bytes;
 
-use IO::Uncompress::RawInflate 2.084 ;
+use IO::Uncompress::RawInflate 2.086 ;
 
-use Compress::Raw::Zlib 2.084 () ;
-use IO::Compress::Base::Common 2.084 qw(:Status );
-use IO::Compress::Gzip::Constants 2.084 ;
-use IO::Compress::Zlib::Extra 2.084 ;
+use Compress::Raw::Zlib 2.086 () ;
+use IO::Compress::Base::Common 2.086 qw(:Status );
+use IO::Compress::Gzip::Constants 2.086 ;
+use IO::Compress::Zlib::Extra 2.086 ;
 
 require Exporter ;
 
@@ -28,7 +28,7 @@ Exporter::export_ok_tags('all');
 
 $GunzipError = '';
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 
 sub new
 {
index 4d89db5..260b762 100644 (file)
@@ -5,15 +5,15 @@ use strict ;
 use warnings;
 use bytes;
 
-use IO::Compress::Base::Common  2.084 qw(:Status );
-use IO::Compress::Zlib::Constants 2.084 ;
+use IO::Compress::Base::Common  2.086 qw(:Status );
+use IO::Compress::Zlib::Constants 2.086 ;
 
-use IO::Uncompress::RawInflate  2.084 ;
+use IO::Uncompress::RawInflate  2.086 ;
 
 require Exporter ;
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $InflateError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $InflateError = '';
 
 @ISA    = qw(IO::Uncompress::RawInflate Exporter);
index 63703cd..0118a22 100644 (file)
@@ -5,16 +5,16 @@ use strict ;
 use warnings;
 use bytes;
 
-use Compress::Raw::Zlib  2.084 ;
-use IO::Compress::Base::Common  2.084 qw(:Status );
+use Compress::Raw::Zlib  2.086 ;
+use IO::Compress::Base::Common  2.086 qw(:Status );
 
-use IO::Uncompress::Base  2.084 ;
-use IO::Uncompress::Adapter::Inflate  2.084 ;
+use IO::Uncompress::Base  2.086 ;
+use IO::Uncompress::Adapter::Inflate  2.086 ;
 
 require Exporter ;
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $RawInflateError);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $RawInflateError = '';
 
 @ISA    = qw(IO::Uncompress::Base Exporter);
index 4e8a0d6..a1ec388 100644 (file)
@@ -9,17 +9,20 @@ use warnings;
 use bytes;
 
 use IO::File;
-use IO::Uncompress::RawInflate  2.084 ;
-use IO::Compress::Base::Common  2.084 qw(:Status );
-use IO::Uncompress::Adapter::Inflate  2.084 ;
-use IO::Uncompress::Adapter::Identity 2.084 ;
-use IO::Compress::Zlib::Extra 2.084 ;
-use IO::Compress::Zip::Constants 2.084 ;
+use IO::Uncompress::RawInflate  2.086 ;
+use IO::Compress::Base::Common  2.086 qw(:Status );
+use IO::Uncompress::Adapter::Inflate  2.086 ;
+use IO::Uncompress::Adapter::Identity 2.086 ;
+use IO::Compress::Zlib::Extra 2.086 ;
+use IO::Compress::Zip::Constants 2.086 ;
 
-use Compress::Raw::Zlib  2.084 () ;
+use Compress::Raw::Zlib  2.086 () ;
 
 BEGIN
 {
+   # Don't trigger any __DIE__ Hooks.
+   local $SIG{__DIE__};
+       
     eval{ require IO::Uncompress::Adapter::Bunzip2 ;
           import  IO::Uncompress::Adapter::Bunzip2 } ;
     eval{ require IO::Uncompress::Adapter::UnLzma ;
@@ -31,7 +34,7 @@ require Exporter ;
 
 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup);
 
-$VERSION = '2.084';
+$VERSION = '2.086';
 $UnzipError = '';
 
 @ISA    = qw(IO::Uncompress::RawInflate Exporter);
@@ -70,6 +73,7 @@ sub getExtraParams
             'name'    => [IO::Compress::Base::Common::Parse_any,       undef],
 
             'stream'  => [IO::Compress::Base::Common::Parse_boolean,   0],
+            'efs'     => [IO::Compress::Base::Common::Parse_boolean,   0],
             
             # TODO - This means reading the central directory to get
             # 1. the local header offsets
@@ -86,6 +90,7 @@ sub ckParams
     $got->setValue('crc32' => 1);
 
     *$self->{UnzipData}{Name} = $got->getValue('name');
+    *$self->{UnzipData}{efs} = $got->getValue('efs');
 
     return 1;
 }
@@ -551,6 +556,7 @@ sub _readZipHeader($)
     my $extraField;
     my @EXTRA = ();
     my $streamingMode = ($gpFlag & ZIP_GP_FLAG_STREAMING_MASK) ? 1 : 0 ;
+    my $efs_flag = ($gpFlag & ZIP_GP_FLAG_LANGUAGE_ENCODING) ? 1 : 0;
 
     return $self->HeaderError("Encrypted content not supported")
         if $gpFlag & (ZIP_GP_FLAG_ENCRYPTED_MASK|ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK);
@@ -565,6 +571,14 @@ sub _readZipHeader($)
     {
         $self->smartReadExact(\$filename, $filename_length)
             or return $self->TruncatedHeader("Filename");
+
+        if (*$self->{UnzipData}{efs} && $efs_flag && $] >= 5.008004)
+        {
+            require Encode;
+            eval { $filename = Encode::decode_utf8($filename, 1) }
+                or Carp::croak "Zip Filename not UTF-8" ;
+        }     
+
         $keep .= $filename ;
     }
 
@@ -705,6 +719,7 @@ sub _readZipHeader($)
         'UncompressedLength' => $uncompressedLength ,
         'CRC32'              => $crc32 ,
         'Name'               => $filename,
+        'efs'                => $efs_flag, # language encoding flag
         'Time'               => _dosToUnixTime($lastModTime),
         'Stream'             => $streamingMode,
 
@@ -1431,6 +1446,18 @@ OPTS is a combination of the following options:
 
 Open "membername" from the zip file for reading.
 
+=item C<< Efs => 0| 1 >>
+
+When this option is set to true AND the zip archive being read has 
+the "Language Encoding Flag" (EFS) set, the member name is assumed to be encoded in UTF-8.
+
+If the member name in the zip archive is not valid UTF-8 when this optionn is true,
+the script will die with an error message.
+
+Note that this option only works with Perl 5.8.4 or better.
+
+This option defaults to B<false>.
+
 =item C<< AutoClose => 0|1 >>
 
 This option is only valid when the C<$input> parameter is a filehandle. If
@@ -1731,6 +1758,10 @@ Skips to the next compressed data stream in the input file/buffer. If a new
 compressed data stream is found, the eof marker will be cleared and C<$.>
 will be reset to 0.
 
+If trailing data is present immediately after the zip archive and the
+C<Transparent> option is enabled, this method will consider that trailing
+data to be another member of the zip archive.
+
 Returns 1 if a new stream was found, 0 if none was found, and -1 if an
 error was encountered.
 
index c339546..08a7d78 100644 (file)
@@ -25,7 +25,7 @@ BEGIN
         if eval { require Test::NoWarnings ;  import Test::NoWarnings; 1 };
 
 
-    my $VERSION = '2.084';
+    my $VERSION = '2.086';
     my @NAMES = qw(
                        Compress::Raw::Bzip2
                        Compress::Raw::Zlib
index f3cb1a3..ae019c8 100644 (file)
@@ -56,7 +56,7 @@ sub readWithGzip
         return 1 
     }
 
-    diag "'$comp' failed: $?";
+    diag "'$comp' failed: \$?=$? \$!=$!";
     return 0 ;
 }
 
@@ -80,7 +80,7 @@ sub writeWithGzip
     return 1 
         if system($comp) == 0 ;
 
-    diag "'$comp' failed: $?";
+    diag "'$comp' failed: \$?=$? \$!=$!";
     return 0 ;
 }
 
diff --git a/cpan/IO-Compress/t/107multi-zip-only.t b/cpan/IO-Compress/t/107multi-zip-only.t
new file mode 100644 (file)
index 0000000..40c7fef
--- /dev/null
@@ -0,0 +1,102 @@
+
+use strict;
+use warnings;
+
+BEGIN {
+    if ($ENV{PERL_CORE}) {
+        chdir 't' if -d 't';
+        @INC = ("../lib", "lib/compress");
+    }
+}
+
+use lib qw(t t/compress);
+
+
+use Test::More ;
+use CompTestUtils;
+
+BEGIN {
+    # use Test::NoWarnings, if available
+    my $extra = 0 ;
+    $extra = 1
+        if eval { require Test::NoWarnings ;  import Test::NoWarnings; 1 };
+
+    plan tests => 21 + $extra ;
+
+    use_ok('IO::Compress::Zip', qw(zip $ZipError)) ;
+
+    use_ok('IO::Uncompress::Unzip', qw($UnzipError)) ;
+    use_ok('IO::Uncompress::AnyUncompress', qw($AnyUncompressError)) ;
+
+}
+
+    my @buffers ;
+    push @buffers, <<EOM ;
+hello world
+this is a test
+some more stuff on this line
+ad finally...
+EOM
+
+    push @buffers, <<EOM ;
+some more stuff
+line 2
+EOM
+
+    push @buffers, <<EOM ;
+even more stuff
+EOM
+
+
+my $name = "n1";
+my $lex = new LexFile my $zipfile ;
+
+my $x = new IO::Compress::Zip($zipfile, Name => $name++, AutoClose => 1);
+isa_ok $x, 'IO::Compress::Zip', '  $x' ;
+
+
+foreach my $buffer (@buffers) {
+    ok $x->write($buffer), "    Write OK" ;
+    # this will add an extra "empty" stream
+    ok $x->newStream(Name => $name ++), "    newStream OK" ;
+}
+ok $x->close, "  Close ok" ;
+
+push @buffers, undef;
+
+{
+    open F, ">>$zipfile";
+    print F "trailing";
+    close F;                    
+}
+
+my $u = new IO::Uncompress::Unzip $zipfile, Transparent => 1, MultiStream => 0
+    or die "Cannot open $zipfile: $UnzipError";
+
+my @names ;
+my $status;
+my $expname = "n1";
+my $ix = 0;
+
+for my $ix (1 .. 4)
+{
+    local $/ ;
+
+    my $n = $u->getHeaderInfo()->{Name};
+    is $n, $expname , "name is $expname";
+    is <$u>, $buffers[$ix-1], "payload ok";
+    ++ $expname;
+
+    $status = $u->nextStream()
+}
+
+{
+    local $/ ;
+
+    my $n = $u->getHeaderInfo()->{Name};
+    is $n, undef , "name is undef";
+    is <$u>, "trailing", "payload ok";
+}
+
+die "Error processing $zipfile: $!\n"
+    if $status < 0 ;
\ No newline at end of file
diff --git a/cpan/IO-Compress/t/112utf8-zip.t b/cpan/IO-Compress/t/112utf8-zip.t
new file mode 100644 (file)
index 0000000..f90a3cb
--- /dev/null
@@ -0,0 +1,220 @@
+BEGIN {
+    if ($ENV{PERL_CORE}) {
+        chdir 't' if -d 't';
+        @INC = ("../lib", "lib/compress");
+    }
+}
+
+use lib qw(t t/compress);
+use strict;
+use warnings;
+use bytes;
+
+use Test::More ;
+use CompTestUtils;
+use Data::Dumper;
+
+use IO::Compress::Zip     qw($ZipError);
+use IO::Uncompress::Unzip qw($UnzipError);
+
+BEGIN {
+    plan skip_all => "Encode is not available"
+        if $] < 5.006 ;
+
+    eval { require Encode; Encode->import(); };
+
+    plan skip_all => "Encode is not available"
+        if $@ ;
+
+    plan skip_all => "Encode not woking in perl $]"
+        if $] >= 5.008 && $] < 5.008004 ;
+
+    # use Test::NoWarnings, if available
+    my $extra = 0 ;
+    $extra = 1
+        if eval { require Test::NoWarnings ;  import Test::NoWarnings; 1 };
+
+    plan tests => 28 + $extra;
+}
+
+{
+    title "EFS set in zip: Create a simple zip - language encoding flag set";
+
+    my $lex = new LexFile my $file1;
+
+    my @names = ( 'alpha \N{GREEK SMALL LETTER ALPHA}',
+                  'beta \N{GREEK SMALL LETTER BETA}',
+                  'gamma \N{GREEK SMALL LETTER GAMMA}',
+                  'delta \N{GREEK SMALL LETTER DELTA}'
+                ) ;
+
+    my @encoded = map { Encode::encode_utf8($_) } @names; 
+
+    my @n = @names;
+
+    my $zip = new IO::Compress::Zip $file1,
+                    Name =>  $names[0], Efs => 1;
+
+    my $content = 'Hello, world!';
+    ok $zip->print($content), "print";
+    $zip->newStream(Name => $names[1], Efs => 1);
+    ok $zip->print($content), "print";
+    $zip->newStream(Name => $names[2], Efs => 1);
+    ok $zip->print($content), "print";
+    $zip->newStream(Name => $names[3], Efs => 1);
+    ok $zip->print($content), "print";
+    ok $zip->close(), "closed";
+
+    {
+        my $u = new IO::Uncompress::Unzip $file1, Efs => 1
+            or die "Cannot open $file1: $UnzipError";
+
+        my $status;
+        my @efs;
+        my @unzip_names;
+        for ($status = 1; $status > 0; $status = $u->nextStream(Efs => 1))
+        {
+            push @efs, $u->getHeaderInfo()->{efs};
+            push @unzip_names, $u->getHeaderInfo()->{Name};
+        }
+
+        die "Error processing $file1: $status $!\n"
+            if $status < 0;
+
+        is_deeply \@efs, [1, 1, 1, 1], "language encoding flag set"
+            or diag "Got " . Dumper(\@efs);
+        is_deeply \@unzip_names, [@names], "Names round tripped"
+            or diag "Got " . Dumper(\@unzip_names);
+    }
+
+    {
+        my $u = new IO::Uncompress::Unzip $file1, Efs => 0
+            or die "Cannot open $file1: $UnzipError";
+
+        my $status;
+        my @efs;
+        my @unzip_names;
+        for ($status = 1; $status > 0; $status = $u->nextStream(Efs => 0))
+        {
+            push @efs, $u->getHeaderInfo()->{efs};
+            push @unzip_names, $u->getHeaderInfo()->{Name};
+        }
+
+        die "Error processing $file1: $status $!\n"
+            if $status < 0;
+
+        is_deeply \@efs, [1, 1, 1, 1], "language encoding flag set"
+            or diag "Got " . Dumper(\@efs);
+        is_deeply \@unzip_names, [@names], "Names round tripped"
+            or diag "Got " . Dumper(\@unzip_names);
+    }    
+}
+
+
+{
+    title "Create a simple zip - language encoding flag not set";
+
+    my $lex = new LexFile my $file1;
+
+    my @names = ( 'alpha \N{GREEK SMALL LETTER ALPHA}',
+                  'beta \N{GREEK SMALL LETTER BETA}',
+                  'gamma \N{GREEK SMALL LETTER GAMMA}',
+                  'delta \N{GREEK SMALL LETTER DELTA}'
+                ) ;
+
+    my @n = @names;
+
+    my $zip = new IO::Compress::Zip $file1,
+                    Name =>  $names[0], Efs => 0;
+
+    my $content = 'Hello, world!';
+    ok $zip->print($content), "print";
+    $zip->newStream(Name => $names[1], Efs => 0);
+    ok $zip->print($content), "print";
+    $zip->newStream(Name => $names[2], Efs => 0);
+    ok $zip->print($content), "print";
+    $zip->newStream(Name => $names[3]);
+    ok $zip->print($content), "print";
+    ok $zip->close(), "closed";
+
+    my $u = new IO::Uncompress::Unzip $file1, Efs => 0
+        or die "Cannot open $file1: $UnzipError";
+
+    my $status;
+    my @efs;
+    my @unzip_names;
+    for ($status = 1; $status > 0; $status = $u->nextStream())
+    {
+        push @efs, $u->getHeaderInfo()->{efs};
+        push @unzip_names, $u->getHeaderInfo()->{Name};
+    }
+
+    die "Error processing $file1: $status $!\n"
+        if $status < 0;
+
+    is_deeply \@efs, [0, 0, 0, 0], "language encoding flag set"
+        or diag "Got " . Dumper(\@efs);
+    is_deeply \@unzip_names, [@names], "Names round tripped"
+        or diag "Got " . Dumper(\@unzip_names);
+}
+
+{
+    title "zip: EFS => 0 filename not valid utf8 - language encoding flag not set";
+
+    my $lex = new LexFile my $file1;
+
+    # Invalid UTF8
+    my $name = "a\xFF\x{100}";
+    
+    my $zip = new IO::Compress::Zip $file1,
+                    Name =>  $name, Efs => 0  ;
+
+    ok $zip->print("abcd"), "print";
+    ok $zip->close(), "closed";
+
+    my $u = new IO::Uncompress::Unzip $file1
+        or die "Cannot open $file1: $UnzipError";  
+
+    ok $u->getHeaderInfo()->{Name} eq $name, "got bad filename";
+}
+
+{
+    title "unzip: EFS => 0 filename not valid utf8 - language encoding flag set";
+
+    my $filename = "t/files/bad-efs.zip" ;
+    my $name = "\xF0\xA4\xAD";
+
+    my $u = new IO::Uncompress::Unzip $filename, efs => 0
+        or die "Cannot open $filename: $UnzipError";  
+
+    ok $u->getHeaderInfo()->{Name} eq $name, "got bad filename";
+}
+
+{
+    title "unzip: EFS => 1 filename not valid utf8 - language encoding flag set";
+
+    my $filename = "t/files/bad-efs.zip" ;
+    my $name = "\xF0\xA4\xAD";
+   
+    eval { my $u = new IO::Uncompress::Unzip $filename, efs => 1
+        or die "Cannot open $filename: $UnzipError" };
+
+    like $@, qr/Zip Filename not UTF-8/,
+            "  Zip Filename not UTF-8" ;
+
+}
+
+{
+    title "EFS => 1 - filename not valid utf8 - catch bad content writing to zip";
+
+    my $lex = new LexFile my $file1;
+
+    # Invalid UTF8
+    my $name = "a\xFF\x{100}";
+    
+    eval { my $zip = new IO::Compress::Zip $file1,
+                    Name =>  $name, Efs => 1 } ;
+
+    like $@,  qr/Wide character in zip filename/, 
+                 "  wide characters in zip filename";
+}
\ No newline at end of file
index 01d2d65..3d6a062 100644 (file)
@@ -439,7 +439,7 @@ foreach my $stdio ( ['-', '-'], [*STDIN, *STDOUT])
 
     # missing parameters
     eval ' $fil = gzopen()  ' ;
-    like $@, mkEvalErr('Not enough arguments for Compress::Zlib::gzopen'),
+    like $@, mkEvalErr('Not enough arguments .*? Compress::Zlib::gzopen'),
         '  gzopen with missing mode fails' ;
 
     # unknown parameters
diff --git a/cpan/IO-Compress/t/files/bad-efs.zip b/cpan/IO-Compress/t/files/bad-efs.zip
new file mode 100644 (file)
index 0000000..642830e
Binary files /dev/null and b/cpan/IO-Compress/t/files/bad-efs.zip differ