2011-02-22 60 views
1

基于this article,我编写了一个perl脚本以允许将文档文件上传到我的网站。但是我得到“不能在upload.cgi第38行使用未定义的值作为HASH参考。” (第38行是except从句之上的那一行)。 作为参考,我的虚拟主机安装了Perl 5.8.8。Perl“未定义值作为HASH参考”错误

#!/usr/bin/perl -wT 

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

$CGI::POST_MAX = 1024 *1024 * 50; #Max file size 50MB 
my $safe_filename_characters = "a-zA-Z0-9_.-"; 
my $upload_dir = "/home/antrobus/Originals"; 

my $query = new CGI; 
my $filename = $query->param("manuscript"); 

if (!$filename) 
{ 
print $query->header (); 
print "The file is too large. Please email me to arrange other means of providing your manuscript."; 
exit; 
} 

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

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

my @allowedtypes = qw(application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document application/vnd.oasis.opendocument.text application/rtf); 
my $type = uploadInfo($filename)->{'Content-Type'}; 
unless ($type = @allowedtypes) 
{ 
print $query->header (); 
print "Filetype not allowed. Please upload doc, docx, odt, or rtf files only."; 
exit; 
} 

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

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

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

close UPLOADFILE; 

print $query->header (); 
print qq~; 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title>File Uploaded!</title> 
    <style type="text/css"> 
    img {border: none;} 
    </style> 
</head> 
<body> 
    <p>Thanks for uploading your manuscript!</p> 
</body> 
</html> 
~; 
+0

'$ type = @ allowedtypes'表达式看起来很腥。除非($ type ~~ @ allowedtypes)',否则会期望类似'unless($ allowedtypes {$ type})'或(with 5.10)''。 –

+0

改为'unless($ allowedtypes {$ type})'会产生以下错误:“全局符号”%allowedtypes“需要在upload.cgi第38行显式包名。” –

回答

1

找到了答案here。显然,检查混乱的方法会干扰检查MIME内容类型的能力。将$filename复制到另一个变量之前,检查并使用其他变量works ...接受它接受任何文件类型,而不仅仅是接受的四个(但这是另一个问题!)

2

如果你想从CGI有MIME内容类型

不喜欢它,

$type = $query->uploadInfo($filename)->{'Content-Type'};CGI对象失踪

看到CGI更多细节, ,特别是

$filename = $q->param('uploaded_file'); 
$type = $q->uploadInfo($filename)->{'Content-Type'}; 
unless ($type eq 'text/html') { 
     die "HTML FILES ONLY!"; 
} 
+0

添加'$ q->'或'$ query->“没有任何作用,我写了我的代码片段基于该CGI文档我删除了$查询对象,因为它最初产生一个未定义的子例程错误 –