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

Discussion in 'Perl' started by Thomas Covello, Feb 2, 2004.

  1. 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.
     
    Thomas Covello, Feb 2, 2004
    #1
    1. Advertising

  2. Thomas Covello

    Cameron Kerr Guest

    [Followup-To set to COL]

    In comp.os.linux Thomas Covello <> 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
    : http://nzgeeks.org/cameron/
    Empowered by Perl!
     
    Cameron Kerr, Feb 2, 2004
    #2
    1. Advertising

  3. Thomas Covello

    Joe Smith Guest

    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
     
    Joe Smith, Feb 2, 2004
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dpackwood
    Replies:
    3
    Views:
    1,872
  2. Hal Vaughan
    Replies:
    11
    Views:
    1,199
    Gordon Beaton
    May 22, 2006
  3. Replies:
    1
    Views:
    470
    mrstephengross
    Jul 25, 2005
  4. Thomas Covello
    Replies:
    4
    Views:
    180
    Ben Morrow
    Feb 2, 2004
  5. PhEaSaNt PLuCKeR

    perl script to pass data to another perl script?

    PhEaSaNt PLuCKeR, Oct 30, 2005, in forum: Perl Misc
    Replies:
    1
    Views:
    175
Loading...

Share This Page