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

T

Thomas Covello

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.
 
C

Cameron Kerr

[Followup-To set to COL]

In comp.os.linux Thomas Covello said:
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.
 
J

Joe Smith

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top