From: Moritz Bunkus Date: Thu, 16 Jan 2014 14:37:53 +0000 (+0100) Subject: Merge branch 'master' of github.com:kivitendo/kivitendo-erp X-Git-Tag: release-3.1.0beta1~21^2~4^2 X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/commitdiff_plain/f796ed261b3ba8503a8bd9f2d9b7effed12355c7?hp=9ea9e4eecc964611216f199a4210c12ba7fe8235 Merge branch 'master' of github.com:kivitendo/kivitendo-erp --- diff --git a/SL/ArchiveZipFixes.pm b/SL/ArchiveZipFixes.pm new file mode 100644 index 000000000..ee5057965 --- /dev/null +++ b/SL/ArchiveZipFixes.pm @@ -0,0 +1,72 @@ +package SL::ArchiveZipFixes; + +use strict; + +use Archive::Zip; +use Archive::Zip::Member; +use version; + +# Archive::Zip contains a bug starting with 1.31_04 which prohibits +# re-writing Zips produced by LibreOffice (.odt). See +# https://rt.cpan.org/Public/Bug/Display.html?id=92205 + +sub _member_writeToFileHandle { + my $self = shift; + my $fh = shift; + my $fhIsSeekable = shift; + my $offset = shift; + + return _error("no member name given for $self") + if $self->fileName() eq ''; + + $self->{'writeLocalHeaderRelativeOffset'} = $offset; + $self->{'wasWritten'} = 0; + + # Determine if I need to write a data descriptor + # I need to do this if I can't refresh the header + # and I don't know compressed size or crc32 fields. + my $headerFieldsUnknown = ( + ( $self->uncompressedSize() > 0 ) + and ($self->compressionMethod() == Archive::Zip::COMPRESSION_STORED + or $self->desiredCompressionMethod() == Archive::Zip::COMPRESSION_DEFLATED ) + ); + + my $shouldWriteDataDescriptor = + ( $headerFieldsUnknown and not $fhIsSeekable ); + + $self->hasDataDescriptor(1) + if ($shouldWriteDataDescriptor); + + $self->{'writeOffset'} = 0; + + my $status = $self->rewindData(); + ( $status = $self->_writeLocalFileHeader($fh) ) + if $status == Archive::Zip::AZ_OK; + ( $status = $self->_writeData($fh) ) + if $status == Archive::Zip::AZ_OK; + if ( $status == Archive::Zip::AZ_OK ) { + $self->{'wasWritten'} = 1; + if ( $self->hasDataDescriptor() ) { + $status = $self->_writeDataDescriptor($fh); + } + elsif ($headerFieldsUnknown) { + $status = $self->_refreshLocalFileHeader($fh); + } + } + + return $status; +} + +sub fix_write_to_file_handle_1_30 { + return if version->new("$Archive::Zip::VERSION")->numify <= version->new("1.30")->numify; + + no warnings 'redefine'; + + *Archive::Zip::Member::_writeToFileHandle = \&_member_writeToFileHandle; +} + +sub apply_fixes { + fix_write_to_file_handle_1_30(); +} + +1; diff --git a/SL/Dispatcher.pm b/SL/Dispatcher.pm index fe992ed2a..f9ad09a87 100644 --- a/SL/Dispatcher.pm +++ b/SL/Dispatcher.pm @@ -26,6 +26,7 @@ use File::Basename; use List::MoreUtils qw(all); use List::Util qw(first); use POSIX; +use SL::ArchiveZipFixes; use SL::Auth; use SL::Dispatcher::AuthHandler; use SL::LXDebug; @@ -51,6 +52,8 @@ sub new { $self->{interface} = lc($interface || 'cgi'); $self->{auth_handler} = SL::Dispatcher::AuthHandler->new; + SL::ArchiveZipFixes->apply_fixes; + return $self; }