如何使用Perl按类型过滤文件上传(例如.png,.bmp,.jpg)

时间:2011-03-07 21:30:33

标签: perl cgi file-type cgi-bin

我使用以下代码:

#!/usr/bin/perl -wT  

use strict;  
use CGI;  
use CGI::Carp qw ( fatalsToBrowser );  
use File::Basename;  

my $query = new CGI;  
my $filename = $query->param("photo");  
my $user_username = $query->param("text_value");  

$CGI::POST_MAX = 1024 * 5000;  
my $safe_filename_characters = "a-zA-Z0-9_.-";  
my $upload_dir = "/" . $user_username;  

if ( !$filename )  
{  
 print $query->header ( );  
 print "There was a problem uploading your photo (try a smaller file).";  
 exit;  
}  

my ( $name, $path, $extension ) = fileparse ( $filename, '\..*' );  
$filename = "user_pro_pic" . ".png";  
$filename =~ tr/ /_/;  
$filename =~ s/[^$safe_filename_characters]//g;  

if ( $filename =~ /^([$safe_filename_characters]+)$/ )  
{  
 $filename = $1;  
}  
else  
{  
 die "Filename contains invalid characters";  
}  

my $upload_filehandle = $query->upload("photo");  

open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";  
binmode UPLOADFILE;  

while ( <$upload_filehandle> )  
{  
 print UPLOADFILE;  
}  

close UPLOADFILE;  

print $query->header ( );   
print "$user_username";
print "<script> location.href='http://google.com/' </script>";

4 个答案:

答案 0 :(得分:2)

结帐Data::FormValidator以及专门上传Data::FormValidator::Constraints::Upload

Data :: FormValidator是处理CGI参数验证的方法。您将验证逻辑分离为一个配置文件,您的自定义验证代码将缩小到几行。

答案 1 :(得分:0)

File::LibMagic是优越的探测器。未测试的:

use File::LibMagic;
my $flm = File::LibMagic->new;
…
my $mime_type = $flm->checktype_filename($filename);
die 'Type not accepted.' unless $mime_type =~ m|image/(?:png|jpeg)|;

答案 2 :(得分:-1)

查看File :: MimeInfo,请参阅: https://metacpan.org/pod/File::MimeInfo

答案 3 :(得分:-1)

在测试无效字符的部分之后,您可以比较文件扩展名的$ filename后缀。当然,这个问题是文件的实际内容可能不匹配(通常会,但你不能总是依赖于此)...

if($ filename =〜/。(jpe?g | gif | png | pdf)$ /){#---检查.jpg,.jpeg,.gif,.png或.pdf
#---支持的文件类型
其他{
#---不支持的文件类型
}

如果你需要实际比较基于MIME类型检测文件内容的类型,那么这将需要更多的处理能力(Apache HTTPd提供了一个模块来检测可能有用的MIME类型,但你可能还需要升级到modperl_2并使用libapreq2来访问这个API。)

但是,对于大多数用途,简单的文件扩展名测试应该没问题。