-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IO::Uncompress::Unzip stream can't be read by Storable (PerlIO) - Demo showing how to fix #33
Comments
Also, FWIW: I did some code reading in Storable that may be helpful. Storable.pm calles the C code For a file handle, PerlIO_read is documented as returning the bytes read. So, this would seem to come down to whether the call to IO::Compress::Base::Common::createSelfTiedObject produces a PerlIO-compatible file handle. And, if as it appears, it does not, what can be done about it. I have the vague sense that perhaps implementing the file handle as a Not being an |
Couldn't leave well enough alone. Layers seems to be on the right track. This proof of concept works, and could be used as the basis of a patch to get The toy example below adds a 'layer' command to the end of the previous reproducer. This provides a custom layer that returns the Storable hash. The second command inserts an intermediate file handle, with a similar layer, between Here are the details: To keep this short - replace the final if( $cmd eq 'layer' ) {
my $bar;
open( my $file, '<:via(ME)', \$bar ) or die( "open $!\n" );
my $read = fd_retrieve( $file );
if( !$read || !exists $read->{key} ){
print "Failed\n";
} else {
print "OK\n";
}
exit;
}
if( $cmd eq 'layereduncompress' ) {
my $in = IO::Uncompress::Unzip->new( \*STDIN, { } ) or die( "IUU\n" );
binmode( $in );
open( my $via, '<:via(TOO)', $in) or die( "via: $!\n" );
my $read = fd_retrieve( $via );
if( !$read || !exists $read->{key} ){
print "Failed\n";
} else {
print "OK\n";
}
exit;
}
die( "Bad command $cmd\n" );
exit;
# Packages implementing PerlIO layers using PerlIO::via
package ME;
my $eof;
sub PUSHED { my($class, $mode, $fh) = @_; bless \*PUSHED, $class };
sub OPEN { my($self, $path, $mode, $fh ) = @_; return 1; };
sub BINMODE { return 0 };
sub FILL { return if $eof; $eof = 1; return pack 'C*', map { eval "0$_" } split( / /, '160 163 164 060 004 011 004 061 062 063 064 004 004 004 010 003 001 000 000 000 012 005 166 141 154 165 145 003 000 000 000 153 145 171'); };
1;
package TOO;
sub PUSHED { my($class, $mode, $fh) = @_; bless {}, $class };
sub OPEN { my($self, $path, $mode, $fh ) = @_; $self->{zip} = $path; return 1; };
sub BINMODE { return 0 };
sub FILL {
my $self = shift;
my $zip = $self->{zip};
return <$zip>;
}
1; The package In the second, the package And in the third, we see that transparent mode thru #./IUZ-Storable.pl layer
OK
# ./JUZ-Storable.pl layereduncompress <foo.zip
OK
#./JUZ-Storable.pl layereduncompress <foo
OK
|
Hi @tlhackque my, you have been busy! Not sure if the problem is with my code or with Also need to check if writing to a file with |
Thanks for the responses. Yes, it's been an adventure - a side trip from my real project. I didn't investigate writes, as my project doesn't require them (yet, anyhow). Agree that they should also provide The issue is that This is a problem in both modules;
So this really needs to be fixed in both places. Either would solve my immediate problem (I'm using the Layers (I pointed you to the documentation on my little adventure) are just a sneaky way of providing a real The short form of my little demo is that
I knew layers exist - but this was my first adventure inside one - so it doesn't take too long to learn - despite the poor documentation. Obviously, I'm no expert. But let me know if I can help explain further. |
I noted another victim of So the good news is: this confirms that you're not alone. The bad news is that the the other victim reported the issue in 2006...and gave up in 2011. Sigh. |
I have a small reproducer demonstrating that IO::Uncompress::Unzip's file descriptor won't work with Storable. Presumably there are other cases...
If I had to guess, it would be that the FH, which is passed to Storable's XS code, may not be positioned (for XS) correctly after header detection...Clearly, it works for ordinary Perl consumers.
Here is the sequence:
\*STDIN
& verify that it's what we wrote. (passes)From this, we can see that the file is written correctly by Storable, and can be read after a trip thru the Zip archive. Further, Storable is happy reading from a file handle.
BUT, neither the raw file nor the Zip member can be read correctly by Storable if IUU is in the middle.
IO::Uncompress::Unzip 2.102
In real life, the work-around is to write all 300MB of uncompressed data to a tempfile, and pass that handle to Storable. Which is suboptimal...
Here is the test program:
And here are the commands (Yes, it fails with newer versions of Perl, and yes in real life there's error checking):
FWIW, strace doesn't show anything odd on the system side of the pipe.
The text was updated successfully, but these errors were encountered: