Skip Menu |

This queue is for tickets about the Archive-Cpio CPAN distribution.

Report information
The Basics
Id: 74256
Status: new
Priority: 0/
Queue: Archive-Cpio

People
Owner: Nobody in particular
Requestors: mrother [...] mail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



Subject: Failure on Win32 (when a cpio-archive contains "\r\n")
It appears the module has never been tested on the Win32 platform. I wanted to use it for some quick modification of a (small) initrd file (e.g. http://distro.ibiblio.org/tinycorelinux/4.x/x86/archive/4.2/ distribution_files/core.gz). An attempt to read the (extracted) cpio archive using the most basic steps: use Archive::Cpio; my $cpio = Archive::Cpio->new; $cpio->read("core.cpio"); resulted in: bad header value 000000us It turns out that the file prior to this failure (i.e. 'usr/sbin/ visudo', which is pretty much the first non-text file in the archive) contains two occurrences of CR-LF (i.e. "0x0d 0x0a"), and therefore the reading of the next header is off by two bytes, which gets reported by the error message above. A simple fix would be to add a 'binmode()' call in 'read()', but considering that 'read_with_handler()' could be called instead I decided to put it in the latter function. Of course another one is also required in 'write()'. So all up the change that worked for me looks like: --- Cpio.pm-orig 2011-05-31 00:09:05.000000000 +1200 +++ Cpio.pm 2012-01-23 19:01:04.390625000 +1300 @@ -92,6 +92,7 @@ } else { open($OUT, '>', $file) or die "can't open $file: $!\n"; } + binmode($OUT); $cpio->write_one($OUT, $_) foreach @{$cpio->{list}}; $cpio->write_trailer($OUT); @@ -170,6 +171,7 @@ my ($cpio, $F, $handler) = @_; my $FHwp = Archive::Cpio::FileHandle_with_pushback->new($F); + binmode($F); $cpio->{archive_format} ||= detect_archive_format($FHwp); while (my $entry = $cpio->{archive_format}->read_one($FHwp)) {
From: mrother [...] mail.com
On second thoughts putting a single 'binmode()' call only into 'write()' might not be such a good idea as both 'write_one()' and 'write_trailer()' could be called directly and therefore 'write()' would have been bypassed. So either 'binmode()' needs to be put either both into 'write_one()' and 'write_trailer()' or some other refactoring is required to get away with a single 'binmode()' call for the cpio archive writing.