preg_match for <?php, <?, and/or ?> - php

I'm not very familiar with regEx's and I'm trying to find a preg_match regex for searching for any of the following strings within a file and if found it will halt it. I already have the fopen and fgets and fclose setup I just need to use a regex inside of a preg_match for the following php tags:
<?php
<?
?>
so if preg_match returns 1 than this will skip this file and not upload it. I am using the $_FILES array to upload it via post, so I'm hoping I can use the $_FILES['file']['tmp_name'] variable for this to read through the file.
Thanks for your help with this :)
EDIT
if (in_array('application/x-httpd-php', $files[$filid]['mimetypes']) && ($_FILES[$value]['type'][$n] == 'application/octet-stream' || $_FILES[$value]['type'][$n] == 'application/octetstream'))
{
$file_extension = strtolower(substr(strrchr($_FILES[$value]['name'][$n], '.'), 1));
if ($file_extension == 'php')
{
// Reading the current php file to make sure it's a PHP File.
$fo = fopen($_FILES[$value]['tmp_name'][$n], 'rb');
while (!feof($fo))
{
$fo_output = fgets($fo, 16384);
// look for a match
if (preg_match([REG EX HERE], $fo_output) == 1)
{
$php = true;
break;
}
}
fclose($fo);
}
}
OK, I apologize, but actually, what I am doing is I need to find a PREG MATCH. Because if it is a PHP FILE, I need to set the MIME TYPE to: application/x-httpd-php within the database. BECAUSE I'm also allowing PHP Files to be uploaded as well in certain instances. So hopefully the code I posted above makes more sense to you all now.
Can someone please help me with a preg_match regex for this please?

/(?:<\?(?!xml)|\?>)/
(15 chars)

If you want to parse the file, try the following instead:
function containsPhp($file) {
if(!$content = file_get_contents($file)) {
trigger_error('Not a file');
return false;
}
foreach(token_get_all($content) as $token) {
if(is_array($token) && in_array(current($token), array(T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO))) {
return true;
}
}
return false;
}
... besides checking for a php extension (php, php5, phtml, inc etc).

\?>|<\?((?=php)|(?!\w))

Related

Download and save a file using php (keeping original filename)

I'm trying to download and save files like this (http://www.example.com/bajar.php?id=420633&u=7) but keeping the original filename.
I've already searched and found this code:
file_put_contents('test.rar', file_get_contents('http://www.example.com/bajar.php?id=420633&u=7');
But in this case I have to put the filename 'test.rar' manually, how can I do the same obtaining the original filename?
Many thanks!
Here's an adaptation of the thread I linked to that should work for your case. The regex is looking for the last '/' and then returning everything after it.
<?php
function get_real($url) {
$headers = get_headers($url);
foreach($headers as $header) {
if (strpos(strtolower($header),'location:') !== false) {
return preg_replace('~.*/(.*)~', '$1', $header);
}
}
}
echo get_real('http://www.example.com/bajar.php?id=420633&u=7');
?>

IF file is !empty ELSE

So, if i have a file that when its empty it requires a specific function, but if the file is NOT empty it will proceed to show (else) something else. This is currently the format I am using. I have tired several different manners and variations of doing so (from PHP Manual examples to StackOverFlow Q/A). What it is doing is showing me the else not the if, since the file is actually empty...
<?
$file = 'config/config2.php';
if(!empty($file))
{
some code here!
}
else
{
some other code here!
}
?>
<?
$file = 'config/config2.php';
if(filesize($file)!=0)// NB:an empty 'looking' file could have a file size above 0
{
some code here!
}
else
{
some other code here!
}
?>
The problem seems to be that you are not actually loading the file before you check if it is empty.
You are only setting the variable $file to the string 'config/config2.php' not actually loading the file.
Before running your if statement do this:
$file = file_get_contents('config/config2.php');
or look into this: http://php.net/manual/en/function.fopen.php

Is there a way to exit only the php file being included?

So, I have a sidebar.php that is included in the index.php. Under a certain condition, I want sidebar.php to stop running, so I thought of putting exit in sidebar.php, but that actually exits all the code beneath it meaning everything beneath include('sidebar.php'); in index.php all the code would be skipped as well. Is there a way to have exit only skip the code in the sidebar.php?
Just use return;
Do also be aware that it is possible to actually return something to a calling script in this way.
if your parent script has $somevar = include("myscript.php"); and then in myscript.php you do say... return true; you will get that value in $somevar
Yes, you just use return;. Your sidebar.php file might look something like this:
<?php
if($certain_condition) {
return;
} else {
// Do your stuff here
}
?>
I know this is a really old question, but I've recently taken over the code base of another developer who used exit religiously, meaning that the parent file that included various files had to be designed in such a way that the include of the module files were done at the end so it didn't cut off the page. I wrote a small PHP script to replace all occurrences of "exit;" with "return;".
if($handle = opendir("path/to/directory/of/files")) {
while(false !== ($file = readdir($handle))) {
if("." === $file) continue;
if(".." === $file) continue;
$pageContents = file_get_contents($file);
$pageContents = str_replace("exit;", "return;", $pageContents);
file_put_contents($file, $pageContents);
echo $file . " updated<br />";
}
}
I hope this helps someone.

How can I get the mime type in PHP

I am writing a script and I need to correctly (I think some mime types can be different from their extensions) get the mime types of files (the files can be of any type).
Web hosting company in use does not have mime_content_type() and is still (don't know which year they will be fixing it) promising to fix the PECL alternative.
Which other way can I go about it (and I don;t have access to shell commands)?
You could try finfo_file - it returns the mime type.
http://php.net/manual/en/book.fileinfo.php
I use the following function, which is a wrapper for the 3 most common methods:
function Mime($path, $magic = null)
{
$path = realpath($path);
if ($path !== false)
{
if (function_exists('finfo_open') === true)
{
$finfo = finfo_open(FILEINFO_MIME_TYPE, $magic);
if (is_resource($finfo) === true)
{
$result = finfo_file($finfo, $path);
}
finfo_close($finfo);
}
else if (function_exists('mime_content_type') === true)
{
$result = mime_content_type($path);
}
else if (function_exists('exif_imagetype') === true)
{
$result = image_type_to_mime_type(exif_imagetype($path));
}
return preg_replace('~^(.+);.+$~', '$1', $result);
}
return false;
}
$_FILES['file']['type'] comes from the browser that uploads the file so you can't rely on this value at all.
Check out finfo_file for identifying file types based on file content. The extension of the file is also unreliable as the user could upload malicious code with an mp3 extension.

How to check file types of uploaded files in PHP?

On the PHP website, the only real checking they suggest is using is_uploaded_file() or move_uploaded_file(), here. Of course you usually don't want user's uploading any type of file, for a variety of reasons.
Because of this, I have often used some "strict" mime type checking. Of course this is very flawed because often mime types are wrong and users can't upload their file. It is also very easy to fake and/or change. And along with all of that, each browser and OS deals with them differently.
Another method is to check the extension, which of course is even easier to change than mime type.
If you only want images, using something like getimagesize() will work.
What about other types of files? PDFs, Word documents or Excel files? Or even text only files?
Edit: If you don't have mime_content_type or Fileinfo and system("file -bi $uploadedfile") gives you the wrong file type, what other options are there?
Take a look at mime_content_type or Fileinfo. These are built-in PHP commands for determining the type of a file by looking at the contents of the file. Also check the comments on the above two pages, there are some other good suggestions.
Personally I've had good luck using something that's essentially system("file -bi $uploadedfile"), but I'm not sure if that's the best method.
IMHO, all MIME-type checking methods are useless.
Say you've got which should have MIME-type application/pdf. Standard methods are trying to find something that looks like a PDF header (%PDF- or smth. like that) and they will return 'Okay, seems like this is a PDF file' on success. But in fact this doesn't means anything. You can upload a file containing only %PDF-1.4 and it will pass MIME-check.
I mean if the file has an expected MIME-type - it will always pass the MIME-type check otherwise the result is undefined.
I assume you are going to have a fixed white-list of file-types that you will accept.
For each of these types, you are going to have to use different techniques to verify that they are valid examples of that format.
There are two related questions:
Does it look roughly like it might be the right type? (For JPEG, you could check the headers, as you mentioned. For many Unix-based formats, you could check the "magic cookie".)
Is it actually a valid example of that type (e.g. For any XML-like format, you could validate against a DTD.)
I think that, for each format, you should ask separate questions for each one, because the answer will be quite different for PDFs compared to ZIP files.
I used mime_content_type that is compatible with PHP 5.2, because I can use neither Fileinfo (it requires PHP 5.3) nor system(), that is disabled by my provider.
For example, I check if a file is a text file so:
if (strcmp(substr(mime_content_type($f),0,4),"text")==0) { ... }
You can see a full example in my "PHP Directory and Subdirectory Listener & File Viewer and Downloader" at:
http://www.galgani.it/software_repository/index.php
if(isset($_FILES['uploaded'])) {
$temp = explode(".", $_FILES["uploaded"]["name"]);
$allowedExts = array("txt","htm","html","php","css","js","json","xml","swf","flv","pdf","psd","ai","eps","eps","ps","doc","rtf","ppt","odt","ods");
$extension = end($temp);
if( in_array($extension, $allowedExts)) {
//code....
} else {
echo "Error,not Documentum type...";
}
}
Here is the function file_mime_type from iZend:
function file_mime_type($file, $encoding=true) {
$mime=false;
if (function_exists('finfo_file')) {
$finfo = finfo_open(FILEINFO_MIME);
$mime = finfo_file($finfo, $file);
finfo_close($finfo);
}
else if (substr(PHP_OS, 0, 3) == 'WIN') {
$mime = mime_content_type($file);
}
else {
$file = escapeshellarg($file);
$cmd = "file -iL $file";
exec($cmd, $output, $r);
if ($r == 0) {
$mime = substr($output[0], strpos($output[0], ': ')+2);
}
}
if (!$mime) {
return false;
}
if ($encoding) {
return $mime;
}
return substr($mime, 0, strpos($mime, '; '));
}
For PHP>=5.3.0, you can use php's finfo_file(finfo_file) function to get the file infomation about the file.
For PHP<5.3.0, you can use your's system's file command to get the file information.
So just make it in one function,
var_dump(mime_type("wiki templete.txt")); // print string(10) "text/plain"
function mime_type($file_path)
{
if (function_exists('finfo_open')) {
$finfo = new finfo(FILEINFO_MIME_TYPE, null);
$mime_type = $finfo->file($file_path);
}
if (!$mime_type && function_exists('passthru') && function_exists('escapeshellarg')) {
ob_start();
passthru(sprintf('file -b --mime %s 2>/dev/null', escapeshellarg($file_path)), $return);
if ($return > 0) {
ob_end_clean();
$mime_type = null;
}
$type = trim(ob_get_clean());
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
$mime_type = null;
}
$mime_type = $match[1];
}
return $mime_type;
}
MimeTypes

Categories