Hello,
I've been working on a download script for an interface to validate users and determine if they have permissions to download files external to the web tree.
The current issue is with a regular expression to check that the file does not start with a "." and has no characters besides
"a-z"
"A-Z"
"0-9"
" " (that's a space)
"/"
","
"-"
"."
I have a working expression to allow all except the space char.
$regexpressfilter = '[a-zA-Z_0-9,./][-a-zA-Z_0-9,./]*$';
Here is the php code to the page with my "new" regexpression to try and allow for spaces in the file name.
<?php
define('FILEDIR', '/TestTree/');
if (isset($_GET[file]) )
$file=$_GET['file'];
elseif (isset($_POST['file']) )
$file=$_POST['file'];
$path = FILEDIR . $file;
//check that this file exists and that it doesn't include
//any special characters no ../ { } !
$regexpressfilter = '^[^.][a-zA-Z_0-9,\\s./][-a-zA-Z_0-9,\\s./]*$';
if (!is_file($path) || !eregi($regexpressfilter, $file) )
{
if (!is_file($path)) header("Location: filegeterror.php?error=1");
else header("Location: filegeterror.php?error");
exit();
}
/*
** //TO BE ADDED check that the user has permission to download file
** if(user does not have permission)
** {
** //redirect to error page
** header("Location: filegeterror.php");
** exit();
** }
*/
$mimetype = array(
'doc'=>'application/msword',
'htm'=>'text/html',
'html'=>'text/html',
'jpg'=>'image/jpeg',
'pdf'=>'application/pdf',
'txt'=>'text/plain',
'xls'=>'application/vnd.ms-excel'
);
$p = explode('.', $file);
$pc = count($p);
//send headers
if(($pc > 1) AND isset($mimetype[$p[$pc - 1]]))
{
//display file inside browser
header("Content-type: " . $mimetype[$p[$pc - 1]] . "\n");
}
else
{
//force download dialog
header("Content-type: application/octet-stream\n");
header("Content-disposition: attachment; filename=\"$file\"\n");
}
header("Content-transfer-encoding: binary\n");
header("Content-length: " . filesize($path) . "\n");
//send file contents
$fp=fopen($path, "r");
fpassthru($fp);
?>
I plan to add the authentication code next, and an additional check for "../" within the $file string, as to prevent a directory traversal. I.E. "/../../../../etc/passwd"
I believe the \s checks for a " " match in a regular expression, but there has to be something wrong as I can download files such as: "test.txt", but not "spaced test.txt".
For reference, here is my "I think this should work" regexpression as entered in my editor: $regexpressfilter = '[.][a-zA-Z_0-9,\s./][-a-zA-Z_0-9,\s./]*$';
Thanks.
P.S. I found the following site with an applet for easily testing regular expressions: http://regexlib.com/RETester.aspx