Home > Software engineering >  "sh: 1: file: not found" thrown in Perl
"sh: 1: file: not found" thrown in Perl

Time:03-23

So this is an issue I see thrown around on several coding help-sites that always have a slight variation. I'm not entirely familiar with what it means, and what's even more curious is that this error is thrown midway through a larger Upload.pm script, and does not cause any sort of fatal error. It gets tossed into my error log somewhere during this unless conditional snippet

     # If this is the first slice, validate the file extension and mime-type. Mime-type of following slices should be "application/octet-stream".
  unless ( defined $response{'error'} ) {
    if ( $slice->{'index'} == 1 ) {
      my ($filename, $directory, $extension) = fileparse($path.$parent_file, qr/\.[^.]*/);

      unless ( is_valid_filetype($slice->{'tmp_file'}, $extension) ) {
        $response{'error'} = "Invalid file type.";
        $response{'retry'} = 0;
      }
    }
  }

Now, let me be perfectly honest. I don't really understand the error message, and I could really use some help understanding it, as well as solving it. Our Perl based web app has refused to let us upload files correctly since upgrading to Debian Bullseye, and I've been stuck debugging this code I didn't write for a few days now. I'm wondering if the upgrade depreciated some Perl modules, or if the directories to said modules are no longer working?

I'm testing this in a Ubuntu based Docker environment running Debian Bullseye on an Apache 2 server.

If you need any more context, clarification, etc, please let me know.

is_valid_filetype() looks like this:

sub is_valid_filetype
{
  my ($tmp_file, $extension) = @_;

  if ( $tmp_file && $extension ) {
    # Get temp file's actual mime-type.
    my $mime = qx/file --mime-type -b '${tmp_file}'/;
    $mime =~ s/^\s |\s $//g;

    # Get valid mime-types matching this extension.
    my $dbh = JobTracker::Common::dbh or die("DBH not available.");
    my $mime_types = $dbh->selectrow_array('SELECT `mime_types` FROM `valid_files` WHERE `extension` = ?', undef, substr($extension, 1));

    if ( $mime && $mime_types ) {
      if ( $mime_types !~ /,/ ) {
        # Single valid mime-type for this extension.
        if ( $mime eq $mime_types ) {
          return 1;
        }
      } else {
        # Multiple valid mime-types for this extension.
        my %valid_mimes = map { $_ => 1 } split(/,/, $mime_types);
        if ( defined $valid_mimes{$mime} ) {
          return 1;
        }
      }
    }
  }

  return 0;
}

CodePudding user response:

It's a message from sh (not Perl). It concerns an error on line 1 of the script, which was apparently an attempt to run the file utility. But sh couldn't find it.

The code in question executes this command using

qx/file --mime-type -b '${tmp_file}'/

Install file or adjust the PATH so it can be found.


Note that this code suffers from a code injection bug. It will fail if the string in $tmp_path contains a single quote ('), possibly resulting in the unintentional execution of code.

Fixed:

use String::ShellQuote qw( shell_quote );

my $cmd = shell_quote( "file", "--mime-type", "-b", $tmp_file" );
qx/$cmd/

CodePudding user response:

Debian Bullseye was reading our CSV files as the wrong mime-type. It was interpreting the file command as application/csv, despite obviously not being an application.

This may be an actual bug in Bullseye, because both my boss and I have scoured the internet with no lucky finding anyone else with this issue. I may even report to Bullseye's devs for further awareness.

The fix was manually adding in our own mime-types that interpreted this file correctly.

It took us dumping the tmp directory to confirm the files existed, and triple checking I had my modules installed.

This was such a weird and crazy upstream issue that either of us could not have imaged it would be the file type interpretation at an OS level in Bullseye.

I really hope this helps someone, saves them the time it took us to find this.

  • Related