Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision fab47672

Von Moritz Bunkus vor fast 11 Jahren hinzugefügt

  • ID fab47672ea774d7218190a2a536876727be5a5de
  • Vorgänger 16b7cb9b
  • Nachfolger f796ed26

Archive::Zip::Member::_writeToFileHandle fixen

Archive::Zip v1.31_04 und neuer enthält einen Bug, durch den von
LibreOffice erzeugte ODTs beim Schreiben der neuen Datei zu einer
Fehlermeldung, damit dem Abbruch der Schreiboperation und letztlich zu
defekten Ausgabedateien führt. Der Bug existiert auch in der aktuellen
Version 1.37.

Daher die Funktion, in der die betroffene Änderung vorgenommen wurde,
Monkeypatchen, bis der Bug behoben ist.

Siehe https://rt.cpan.org/Public/Bug/Display.html?id=92205

Unterschiede anzeigen:

SL/ArchiveZipFixes.pm
1
package SL::ArchiveZipFixes;
2

  
3
use strict;
4

  
5
use Archive::Zip;
6
use Archive::Zip::Member;
7
use version;
8

  
9
# Archive::Zip contains a bug starting with 1.31_04 which prohibits
10
# re-writing Zips produced by LibreOffice (.odt). See
11
# https://rt.cpan.org/Public/Bug/Display.html?id=92205
12

  
13
sub _member_writeToFileHandle {
14
    my $self         = shift;
15
    my $fh           = shift;
16
    my $fhIsSeekable = shift;
17
    my $offset       = shift;
18

  
19
    return _error("no member name given for $self")
20
      if $self->fileName() eq '';
21

  
22
    $self->{'writeLocalHeaderRelativeOffset'} = $offset;
23
    $self->{'wasWritten'}                     = 0;
24

  
25
    # Determine if I need to write a data descriptor
26
    # I need to do this if I can't refresh the header
27
    # and I don't know compressed size or crc32 fields.
28
    my $headerFieldsUnknown = (
29
        ( $self->uncompressedSize() > 0 )
30
          and ($self->compressionMethod() == Archive::Zip::COMPRESSION_STORED
31
            or $self->desiredCompressionMethod() == Archive::Zip::COMPRESSION_DEFLATED )
32
    );
33

  
34
    my $shouldWriteDataDescriptor =
35
      ( $headerFieldsUnknown and not $fhIsSeekable );
36

  
37
    $self->hasDataDescriptor(1)
38
      if ($shouldWriteDataDescriptor);
39

  
40
    $self->{'writeOffset'} = 0;
41

  
42
    my $status = $self->rewindData();
43
    ( $status = $self->_writeLocalFileHeader($fh) )
44
      if $status == Archive::Zip::AZ_OK;
45
    ( $status = $self->_writeData($fh) )
46
      if $status == Archive::Zip::AZ_OK;
47
    if ( $status == Archive::Zip::AZ_OK ) {
48
        $self->{'wasWritten'} = 1;
49
        if ( $self->hasDataDescriptor() ) {
50
            $status = $self->_writeDataDescriptor($fh);
51
        }
52
        elsif ($headerFieldsUnknown) {
53
            $status = $self->_refreshLocalFileHeader($fh);
54
        }
55
    }
56

  
57
    return $status;
58
}
59

  
60
sub fix_write_to_file_handle_1_30 {
61
  return if version->new("$Archive::Zip::VERSION")->numify <= version->new("1.30")->numify;
62

  
63
  no warnings 'redefine';
64

  
65
  *Archive::Zip::Member::_writeToFileHandle = \&_member_writeToFileHandle;
66
}
67

  
68
sub apply_fixes {
69
  fix_write_to_file_handle_1_30();
70
}
71

  
72
1;
SL/Dispatcher.pm
26 26
use List::MoreUtils qw(all);
27 27
use List::Util qw(first);
28 28
use POSIX;
29
use SL::ArchiveZipFixes;
29 30
use SL::Auth;
30 31
use SL::Dispatcher::AuthHandler;
31 32
use SL::LXDebug;
......
51 52
  $self->{interface} = lc($interface || 'cgi');
52 53
  $self->{auth_handler} = SL::Dispatcher::AuthHandler->new;
53 54

  
55
  SL::ArchiveZipFixes->apply_fixes;
56

  
54 57
  return $self;
55 58
}
56 59

  

Auch abrufbar als: Unified diff