Solved

php, file upload to directory with "spaces" in title?

Posted on 2015-01-05
20
118 Views
Last Modified: 2015-01-11
I am using this code when trying to upload a file into a directory:

	
if(move_uploaded_file($_FILES['upl']['tmp_name'], '../'.$acct_id.'/music/'.$playlist.'/'.$_FILES['upl']['name'])){
echo '{"status":"success"}';
exit;
}

Open in new window


It works fine as long as the $playlist variable is a single string (with no spaces)

But when the variable $playlist is something like "Greatest Hits" with the space between the two words, the code will not work?

I did try adding the rawurlencode($playlist) as suggested by a friend but still no luck:

if(move_uploaded_file($_FILES['upl']['tmp_name'], '../'.$acct_id.'/music/'.rawurlencode($playlist).'/'.$_FILES['upl']['name'])){
echo '{"status":"success"}';
exit;
}

Open in new window


Suggestions are greatly appreciated.
 Thank You, The American Cowboy
0
Comment
Question by:edavo
  • 10
  • 5
  • 3
  • +1
20 Comments
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 40533013
>rawurlencode
actually, if in the url you pass a "space", that one should have been url encoded; and hence in the code there you use urldecode (and not urlencode)

the " " is represented by "%20", for example.
0
 

Author Comment

by:edavo
ID: 40533019
Not sure I understand… How would you suggest I append this code?
'../'.$acct_id.'/music/'.$playlist.'/'.$_FILES['upl']['name']

Open in new window

0
 

Author Comment

by:edavo
ID: 40533022
As I said this works with "no space title" but not with "space titles"
0
 

Author Comment

by:edavo
ID: 40533032
But the problem is that I need it to work with both "no space title" and "space titles" - any suggestions?

Thank You - AC
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 40533046
this is the code line, normally
'../'.$acct_id.'/music/'.$playlist.'/'. rawurldecode($_FILES['upl']['name'])

but as said, the url needs to be like this when it comes in for that:
"space%20with%20spaces"

if that does not solve the issue, please clarify exactly what "error" you get, or where exactly it fails.
0
 

Author Comment

by:edavo
ID: 40533066
I will try to explain a different way.

The problem in the string is with the $playlist variable, not the file name being uploaded.

It appears to me that your suggestion places the "rawurldecode" on the file name being uploaded.

The files that I am uploading do have spaces and they work fine as long as the $playlist has no spaces, so the problem is with the directory title which is being placed inside $playlist.

I have tried:
- htmlentities($playlist)
- urlencode($playlist)
- urldecode($playlist)
- rawurlencode($playlist)
- rawurldecode($playlist)

Does this make sense?
Thank You - AC
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 40533089
sorry, wrong place indeed.

does the file system in which you want to place the playlist folder allow spaces?
again: what exact error do you get?
if you don't get an error, but it "does not work" just means the error handling is "hiding" the error, which means you first need to debug and enable the error logging
0
 
LVL 82

Assisted Solution

by:Dave Baldwin
Dave Baldwin earned 100 total points
ID: 40533091
Directories are not allowed to have spaces on some file systems.  The space Must be eliminated or 'escaped' or replaced with another character.  See Note 1 on this page:  http://en.wikipedia.org/wiki/Filename
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 40533096
Let me put it a different way.  I never allow spaces in directory and file names because it Always seems to end up being a problem.
0
 

Author Comment

by:edavo
ID: 40533190
I don't get an error. It just doesn't upload. The uploader goes through the motion (animated progress bar) but when I check, the file is not in the directory. Again when it is a "no space" directory, everything acts the same but the file IS placed.

Regarding spaces in general. I agree that there should be no spaces, but this is a UX issue as well. The general public does not want to name their playlists "My-Favotite-Hits" or "Hits_of_the_1980s" so I can't do it directly. Perhaps I can indirectly, by making all directories "no-space" and then just encoding/decoding when I display on the page? But I was thinking there must be an easier way because I am so close.

Re "Directories are not allowed to have spaces on some file systems." I think it is acceptable on my host, only because it is working with the track titles, but not the $playlist variable...
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 142

Assisted Solution

by:Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3] earned 100 total points
ID: 40533198
I think you may want to create a table/file that sets the "display name" of the playlist, while the folder may have a different (cleaned) name.
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 40533204
You really should read that article.  Especially the part about having to quote directory or file names with spaces in them.  Even Windows requires that.

And the 'general public' is not going to keep your application running.
0
 

Author Comment

by:edavo
ID: 40533239
Thank you - Read and understood. But there has to be a middle ground - Dev and UX.

I will not require my users to create "no space" playlists. If programmers don't understand this, they have no idea about the importance of UX and we're miles apart. (Read "The Inmates Are Running The Asylum" by Allen Cooper) Perhaps the solution is as Guy (and I) referenced, we allow the users to input spaced names, and then code them as "no space" on the back end. Then we simply encode/decode them with spaces when they are displayed in the app. This just seems terribly in-efficient.

I will still hold out for someone to add contributions to the problem as it is very close to working:

if(move_uploaded_file($_FILES['upl']['tmp_name'], '../'.$acct_id.'/music/'.$playlist.'/'.$_FILES['upl']['name'])){
echo '{"status":"success"}';
exit;
}

Open in new window


In the meantime, I'll continue to plug away and keep you posted.

Others please weigh in...

Thank You AC
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 40533280
BTW, you are now "blocked" by spaces, what about other special characters that the "OS" may not be able to handle:
$   like for KE$HA : en.wikipedia.org/wiki/Kesha)
!   like I know a DJ that is named   DJ!    
and surely you will find other stuff.
0
 

Author Comment

by:edavo
ID: 40533285
Good point - Yikes! I don't have a problem laying down "some" rules. This could be done and still considered middle ground - Dev and UX

But I will have to be ready for those - I think I can catch those in the earlier stage - when playlists are created.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 300 total points
ID: 40533320
No points for this -- I think the issue about blanks in file paths has been well enough explained.  Here is a good place for you to consider the difference between your internal requirements and a client-facing presentation of the data.  When your clients get to specify which directory they will use on your server, you're only one hacker away from disaster.  So create two lists - one that has the list of directories that the client can use, and another list that has the list of directory names that the client can see.  There should be a one-to-one correspondence between these lists.  When your script receives any input destined for a directory that is not in the first list, you can safely discard it because it did not come from your server and it therefore represents an attack vector.  Here's how you might do that.
http://iconoun.com/demo/temp_edavo.php
<?php // demo/temp_edavo.php

/**
 * SEE http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28591309.html
 */
error_reporting(E_ALL);

/**
 * A list of allowable directories
 */
$genres = array
( 'country' => 'Country'
, 'western' => 'Western'
, 'pop'     => 'Pop'
, 'a_13'    => 'Greatest Hits'
)
;

/**
 * If there has been an HTTP request, automagically translate the client input
 * into an acceptable representation of the request
 */
if (!empty($_POST['genre']))
{
    $g_key = array_key_exists($_POST['genre'], $genres) ? $_POST['genre'] : NULL;
    if ($g_key)
    {
        echo PHP_EOL . "You chose genre: $genres[$g_key] (directory: $g_key)";
    }
}
/**
 * Create the form "options" tags for client input
 */
$options = '<option value="">Choose Genre</option>';
foreach ($genres as $dir => $name)
{
    $options
    .= '<option value="'
    . $dir
    . '">'
    . $name
    . '</option>'
    . PHP_EOL
    ;
}

/**
 * Create the form using the options tags
 */
$form = <<<EOD
<form method="post">
<select name="genre">
$options
</select>
<input type="submit" />
</form>
EOD;

echo $form;

Open in new window

0
 

Author Comment

by:edavo
ID: 40533340
Based on David, Guy and Ray's suggestion. I had to use the

    $playlist = str_replace('-', ' ', $playlist);

so in effect, when a user CREATES a new playlist, the spaces are replaced out with dashes (-) AND LIKEWISE when the playlist is DISPLAYED ON THE USER SIDE, I do the opposite and replace out the dashes with the spaces so that it displays properly

    $playlist = str_replace(' ', '-', $playlist);

This solved the problem and the upload doesn't have to deal with the dreaded spaces. And the user still sees the Names as they created them - Thank you all very much! AC
0
 

Assisted Solution

by:edavo
edavo earned 0 total points
ID: 40533344
Ray - Good advice on the hacker possibility. The users can create their own directory names, but the directories only accept .mp3, .ogg, .m4a and .wav files as restricted by Php - is it still easy for them to threaten the system based on the filetype upload restrictions?

Thank You - AC
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40533565
is it still easy for them to threaten the system...
Not sure.  How may directories are they allowed to create over what period of time?  Is there a financial disincentive for creating directories (ie, you automatically charge their credit cards)?  I think I would want to add some friction (perhaps a CAPTCHA) to a system that allows clients to make changes on my server.
0
 

Author Closing Comment

by:edavo
ID: 40542925
Excellent help and advice.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Consider the following scenario: You are working on a website and make something great - something that lets the server work with information submitted by your users. This could be anything, from a simple guestbook to a e-Money solution. But what…
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now