Mystery echo - can't find why - php

So I've made this upload script and to make it more secure, I'm finding out the type of each file.
However, for some reason, the filetype is being echoed back to me!
For example:
image/jpeg; charset=binary Please upload only SWF files!
The echoed string looks same when the upload is successful.
The code:
<?php session_start();
defined('IN_SCRIPT') ? NULL : define('IN_SCRIPT', NULL);
require_once 'inc/db_connect.php';
require_once 'styles/import.php';
$style = new style_class(NULL);
if(!isset($_FILES['file']['tmp_name']) || empty($_FILES['file']['tmp_name'])) die($style->upload_no_parameter());
$filetype = system('file -bi '.$_FILES['file']['tmp_name']);
$filetype = explode(';', $filetype, 1);
if ($filetype[0] != 'application/x-shockwave-flash; charset=binary') die($style->upload_wrong_format());
$sha256 = hash_file("sha256", $_FILES['file']['tmp_name']);
$query = $db->prepare('SELECT id FROM swf WHERE hash = :hash');
$result = $query->execute(array(':hash'=>$sha256));
if ($query->rowCount() != 0) die($style->upload_duplicate());
$query = $db->query('SELECT * FROM swf ORDER BY id DESC LIMIT 1;');
$name = $query->fetch(PDO::FETCH_ASSOC);
$new_name = 'uploads/'.($name['id']+1).'.swf';
if(move_uploaded_file($_FILES['file']['tmp_name'], $new_name)) {
$query = $db->prepare('INSERT INTO swf (uploader, upload_time, hash) VALUES (:id, NOW(), :hash);');
$query->execute(array(':id' => $_SESSION['id'], ':hash'=> $sha256));
echo $style->upload_success();
}
else
echo $style->upload_fail();
?>
I can't see why the script would do such echo...
Thank you!
EDIT:
The style_class was the first place where I looked. This class contains functions returning mainly HTML text. The whole class is auto-generated from database.
I'm copying here the upload_* from the generated file, so you can see:
class style_class{
function upload_no_parameter(){
echo "<b>All parameters must be set!</b>";
}
function upload_fail(){
echo "<b>There was an error, please try again.</b>";
}
function upload_success(){
echo "<b>Your SWF has been uploaded!</b>";
}
function upload_duplicate(){
echo "<b>File already exists!</b>";
}
function upload_wrong_format(){
echo "<b>Please upload only SWF files!</b>";
}
}
Thank you!

I'd bet die($style->upload_wrong_format()) is causing the issue. Check that function.

You've got some very nasty logic bugs in your code:
1) Assuming the file upload succeeded. Proper error handling goes like this:
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
die("File upload failed with error code " . $_FILES['file']['error']);
}
Checking any of the other fields in any file upload is not proper - those fields can still be present and populated even for a failed upload. The error codes are documented here: http://php.net/manual/en/features.file-upload.errors.php
2) you're using exec() and calling file to determine mimetypes. Why? PHP has the finfo library for just this purpose: http://php.net/manual/en/book.fileinfo.php it uses the same magic numbers library as file and doesn't require an exec() call to work.
3) You have a very racey error-prone method of getting an ID number for your swf:
$query = $db->query('SELECT * FROM swf ORDER BY id DESC LIMIT 1;');
$name = $query->fetch(PDO::FETCH_ASSOC);
$new_name = 'uploads/'.($name['id']+1).'.swf';
Nothing says that another script cannot execute AND complete in the time you fetch this ID number and the time you complete thigns here. A proper method is to start a transaction, insert a skeleton record into the DB, retrieve its auto_increment primary key, then update the record and do your file moves with that id. It'll be guaranteed to be unique, whereas at some point your code WILL fail and stomp on another upload.

Related

error to upload to images with php

I am trying to upload two images with php. And add them to the database. Somehow it only uploads one image and the records in the database always have the same values.
this is the code i use
<?php
include "../connect.php";
$name1 = $_FILES['pic1']['name'];
$size1 = $_FILES['pic1']['size'];
$name2 = $_FILES['pic2']['name'];
$size3 = $_FILES['pic2']['size'];
if(isset($_POST['name']))
{
$extension1 = pathinfo($name1,PATHINFO_EXTENSION);
$array = array('png','gif','jpeg','jpg');
if (!in_array($extension1,$array)){
echo "<div class='faild'>".$array[0]."-".$array[1]."-".$array[2]."-".$array[3]." --> (".$name.")</div>";
}else if ($size>10000000){
echo "<div class='faild'>Size</div>";
}else {
$new_image1 = time().'.'.$extension1;
$file1 = "images/upload";
$pic1 = "$file1/".$new_image1;
move_uploaded_file($_FILES["pic1"]["tmp_name"],"../".$pic1."");
$insert = mysql_query("update temp set pic='$pic1' ") or die("error ins");
}
$extension2 = pathinfo($name2,PATHINFO_EXTENSION);
$array = array('png','gif','jpeg','jpg');
if (!in_array($extension2,$array)){
echo "<div class='faild'>".$array[0]."-".$array[1]."-".$array[2]."-".$array[3]." --> (".$name.")</div>";
}else if ($size>10000000){
echo "<div class='faild'>Size</div>";
}else {
$new_image2 = time().'.'.$extension2;
$file2 = "images/upload";
$pic2 = "$file2/".$new_image2;
move_uploaded_file($_FILES["pic2"]["tmp_name"],"../".$pic2."");
$insert = mysql_query("update temp set passport='$pic2'") or die("error ins");
}
}
?>
One of the problems you have is with your update statement. There is no 'where' statement saying which record in the database should be updated so this query updates them all. That's why you only have the last image in all the database rows.
Besides that, your code is not very good from a security point of view. You should take a look at mysqli or pdo for your database connection and queries because MySQL is deprecated and removed from PHP. Also take a look at SQL injections and data validation. Besides some very basic extension and size validation there is nothing there to keep things save. Try escaping and validating all user inputs.
And another point would be to take a look at 'functions'. You're running almost the exact same piece of code at least twice. And every code change has to be done twice. Perfect for a function call, something like
function storeImage($image){
// write the uploading and storing PHP here
}

Check for duplicate images and videos in database/folder

Is there a way to check whether an image or video already exists in a mysql database or a specific folder when the names are different. Also note there could be 10 to 1000 images in the database or folder and this would need to be done via php.
Thanks for the help
Each file will (for practical purposes) have a unique hash, so you can save the hashes of your files (see sha1_file or md5_file) to the db and if the hash of your new file is in your db, then it already exists.
$newFileHash = sha1_file('myNewFile.txt');
$query = "SELECT 1 FROM myHashes WHERE file_hash = '$newFileHash'";
$rs = mysqli_query($query);
if(mysqli_num_rows($rs)) {
echo "the file already exists!";
}
else {
//insert $newFileHash into your db here
}
You can get the base64 encoded data information of the images/videos
$file = file_get_contents('path/file.zip');
$file_encoded = base64_encode($file);
And then compare the $file_encoded with whatever you have in your database.
if ($file_encoded === $file_encoded_in_db) {
//Files are the same
}

PHP: define name for file upload

I have a peace of code that stores profile images in the map "images/profiles" and stores the URL in the database. I want to define the name of the uploaded profile picture to be the $ID of the user. How can I do this?
include("../../core/init.inc.php");
$target = "../images/profiles/";
$target = $target . basename($_FILES['photo']['name']);
$pic = $_FILES['photo']['name'];
if(move_uploaded_file($_FILES['photo']['tmp_name'], $target)) {
echo "The file ". basename($_FILES['photo']['name']). " has been uploaded";
} else {
echo "ERROR";
}
mysql_query("UPDATE users SET image_url='includes/images/profiles/$pic' WHERE username = '".mysql_real_escape_string($_SESSION['username'])."'");
Now when someone uploads his profile picture (lets call it pf1.png) it saves it as "pf1.png". I want it to be saved like "$ID.png" (.png being a random extension). I want to accomplish this both for the move_upload_file function and updating the 'image_url' database column correctly.
According to the example in the documentation you can provide the filename in the destination of move_uploaded_file(). If that fails you can simply rename() the file after saving it.
try changing
$target = $target . basename($_FILES['photo']['name']);
to:
$filename=$_FILES["file"]["tmp_name"];
$extension=end(explode(".", $filename));
$target = target . $_SESSION["ID"].".".$extension;
side note: You are not escaping $pic this makes your site vulnerable to sql-injection
I don't know how you saved the ID of the user, but to make it easy let's assume you stored the ID in a session.
Then simply change the $target.
$target = $target . $_SESSION['ID'];
Also change your query as follows:
$url = "includes/images/profiles/" . $_SESSION['ID'];
SET image_url="$url"
Note: I don't know why you got an image folder inside an includes folder, but I guess you made that choice for yourself.
you can get the last inserted id and make it as a name of your image/uploaded file
$qry = mysqli_query($dbconnection,"INSERT INTO statements here");
$last_id = mysqli_insert_id($dbconnection);
//$ext= you get the extension of the file uploaded
move_uploaded_file($tmpname,$target.$last_id.$ext);
now if you want it to be accomplished in updating also.
you can always get the ID of the data you want to fetch and make it as a basis in updating.
ex.
$id = $_GET['id'] || $id = $row['id']; //anything depends on how you want it to retrieve
then you can do the query and move_uploaded_file function
$qry = mysqli_query($dbconnection,"UPDATE tblname SET field='$anything' WHERE id = '$id'");
move_uploaded_file($tmpname,$target.$id.$ext);
of course $tmpname will be the basis on what file you have uploaded, $tmpname will be the file you want to move into your desired directory

PHP Connection Timeout Issue

In one of my application, users can upload CSV file (| separated fields), after uploading I am storing all the content of file in temporary table (I truncate this table every time for new upload so that it contains the current file data). After that I am iterating over each and every row of that table, and performs some database operation as per the business logic.
The following code will illustrate this:
if(isset($_POST['btn_uploadcsv']))
{
$filename = $_FILES["csvupload"]["name"];
$uploads_dir = 'csvs'; //csv files...
$tmp_name = $_FILES["csvupload"]["tmp_name"];
$name = time();
move_uploaded_file($tmp_name, "$uploads_dir/$name");
$csvpath = "$uploads_dir/$name";
$row = 0;
$emptysql = "TRUNCATE TABLE `temp`";
$connector->query($emptysql);
if (($handle = fopen($csvpath, "r")) !== FALSE) {
$str_ins = "";
while (($data = fgetcsv($handle, 1000, "|")) !== FALSE) {
/*
* Here I am getting the column values to be store in the
* the table, using INSERT command
*/
unset($data);
}
fclose($handle);
}
/*Here I am selecting above stored data using SELECT statement */
for($j=0;$j<count($allrecords);$j++)
{
echo "In the loop";
/*If I use echo statement for debugging it is working fine*/
//set_time_limit(300);
/* I have tried this also but it is not working*/
if(!empty($allrecords[$j]['catid']))
{
// Here is my business logic which mailny deals with
// conditional DB operation
}
echo "Iteration done.";
/*If I use echo statement for debugging it is working fine*/
}
}
The problem is when I execute aboe script on server it is giving server timeout error. But when I test above script on my localhost, is is working fine.
Also as mentioned in the code, if I use echo statements for debugging, then it is working fine, and when I remove that it starts giving connection timeout problem.
I have tried set_time_limit(300), set_time_limit(0), but none of them seems to work.
Any idea, how can I resolve the above problem.
-- Many thanks for your time.
Edit:
I have checked that, files are uploading on the server.
set_time_limit
change to
ini_set("max_execution_time",300);
When max_execution_time is not set in php.ini set_time_limit valid.
I have resolved the issue using flush, to send intermediate output to the browser, while the query is executing in the background.
This is how I modified the code:
for($j=0;$j<count($allrecords);$j++)
{
/*At the end of each iteration, I have added the following code*/
echo " ";
flush();
}
Thanks to the contributors over this link PHP: Possible to trickle-output to browser while waiting for database query to execute?, from where I got inspiration.

PHP upload file

i have been stressing for an hour at this stupid script i am trying to make it uploa an MP3
file to a folder it creates.
It is putting the information into mysql and making the folder bu when i ftp the folder is empty with no music file in there
here is the script thanks so so so much!
BTW $name is the POSTED name and full name is the posted name + ".mp3"
// BEGIN ENTERING INFORMATION TO MYSQL TABLE
$sql = mysql_query("INSERT INTO mattyc (name, date, length, size, link)
VALUES('$name','$date','$length','$size','$link')"
) or die (mysql_error());
mkdir("../music/albums/donjuma/$name", 0777);
$song = ("../music/albums/donjuma/$name/$fullname");
if (file_exists($song)) {
unlink($song);
}
$newname = "$fullname";
$newfile = rename(($_FILES['song']['tmp_name']),($newname));
$place_file = move_uploaded_file( $newfile, "../music/albums/donjuma/$name/"."$newname");
$success_msg = "<font color=\"#009900\">Your SONG has been updated, it may take a few minutes for the changes to show... please be patient.</font>";
echo $success_msg;
}
}
}
$newfile =
rename(($_FILES['song']['tmp_name']),($newname));
$place_file = move_uploaded_file(
$newfile,
"../music/albums/donjuma/$name/"."$newname");
rename() returns a bool, not a filename. So your move_uploaded_file() call is going to fail. Any file renaming should be part of your move_uploaded_file() call, don't try and do anything with your temporary file apart from move it.

Categories