470,590 Members | 2,456 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,590 developers. It's quick & easy.

bunzip2 when exec()-ed from perl script outputs garbage data.

Hello,
When the following perl script is executed:

#!/usr/bin/env perl
use strict;
use diagnostics;
use warnings;

# Header bytes for different zip formats
my $GZIP_HEADER = "\x1f\x8b\x08\x08";
my $BZIP_HEADER = "BZh9"; # 42 5a 68 39

my $header_bytes;

read STDIN, $header_bytes, 4 or die "Trouble reading input: $!";
if ($header_bytes eq $GZIP_HEADER) {
exec "gunzip -f";
die "gunzip doesn't exist or can't be accessed: $!";
} elsif ($header_bytes eq $BZIP_HEADER) {
exec "bunzip2 -f";
die "bunzip2 doesn't exist or can't be accessed: $!";
} else { die "Not a proper zip file or unsupported zip format." }

I get output like this:
BZh91AY (blah blah blah.... I can't copy it because it contains NULs)

I've used print statements to prove that it executed bzip2 and found the
correct magic number.
Jul 19 '05 #1
2 3781
Thomas Covello wrote:

read STDIN, $header_bytes, 4 or die "Trouble reading input: $!";
You have consumed four bytes from the input stream.
exec "gunzip -f";
exec "bunzip2 -f";


These program need to see the entire file, including the
four bytes that you consumed. You'll have to put those
four bytes back into the stream that the program reads.
-Joe
Jul 19 '05 #2
[Followup-To set to COL]

In comp.os.linux Thomas Covello <pm********@shaw.ca> wrote:
read STDIN, $header_bytes, 4 or die "Trouble reading input: $!";
if ($header_bytes eq $GZIP_HEADER) {
exec "gunzip -f";
die "gunzip doesn't exist or can't be accessed: $!";
} elsif ($header_bytes eq $BZIP_HEADER) {
exec "bunzip2 -f";
die "bunzip2 doesn't exist or can't be accessed: $!";
} else { die "Not a proper zip file or unsupported zip format." }


You have a fundamental flaw. You are reading in 4 bytes from stdin, and
then execing gunzip or bunzip, which will read in the data, but it WON'T
get the 4 bytes you've already read in, therefore the header won't be
recognised, and you'll get an error, or something weird.

You need to either find some way of peeking the contents of stdin
(without removing it from the queue (you'll likely need to use sysread),
or don't take the input from stdin. Take it from a file instead, that

Also, if you don't redirect the output of this program, you're going to
get (very likely) binary gibberish being output. But you probably knew
that part already.

--
Cameron Kerr
ca**********@paradise.net.nz : http://nzgeeks.org/cameron/
Empowered by Perl!
Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by comp.lang.php | last post: by
1 post views Thread by Matimus | last post: by
reply views Thread by Gordon Fraser | last post: by
reply views Thread by Chris Rebert | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.