A JM Posted April 17, 2015 Share Posted April 17, 2015 I've got a problem hopefully someone can assist with when unlinking files it has to do with file names that have spaces in them. If the file name contains no spaces the name is displayed correctly and the URL is complete. However if the file name contains spaces, the filename is displayed correctly but the URL is truncated at the space and the delete routine doesn't work, I must be missing something obvious here???? Any ideas on how to fix? <?php //initialize the session if (!isset($_SESSION)) { session_start(); } $claim_folder= $_SESSION['port_recordID']; //variable comes from detail page only used to carry claimnumber $path = "../docs/" . $doc_folder . "/"; if(isset($_GET['delete']) && $_GET['delete']=='true') { $fname = $_GET['deletefile']; $fID = $_GET['recordid']; $path = '../claims/' . $fID . '/'; print_r($path.$fname); //exit(); unlink($path.$fname); //header('location: file_list.php'); die(); } ?> <?php $dir = dir($path); while($file = $dir->read()) { if($file != '.' && $file != '..') { echo "<form method='post' action="?><?php echo $_SERVER['PHP_SELF'].'?delete=true&recordid='.$doc_folder.'&deletefile='.$file;?> <?php echo" ><a href= /pages/download.php?file=$file> $file </a> <input type='submit' value='delete'></form>"; } } ?> AJM, Quote Link to comment Share on other sites More sharing options...
Tom10 Posted April 17, 2015 Share Posted April 17, 2015 (edited) if(preg_match("%[^\w\s\b\/\%\&\?\=\-\.\_]%", $_GET['delete'])) { } else { } Not sure if that would work, i was thinking make a regular expression if there are spaces in the url do nothing Edited April 17, 2015 by Tom10 Quote Link to comment Share on other sites More sharing options...
A JM Posted April 17, 2015 Author Share Posted April 17, 2015 I think I need to lean more towards urlencode()? As long as the filename doesn't contain a "space" then the routine works as designed.. I' m trying to figure out what's happening first so that I can make a better assesment of how to fix it, thanks for the suggestion. AJM, Quote Link to comment Share on other sites More sharing options...
requinix Posted April 17, 2015 Share Posted April 17, 2015 (sigh) You should always put quotes around attributes in HTML. If you don't do that then spaces will mess it up and you'll lose stuff. Also, PHP_SELF is not safe to use unless you wrap it in a function like htmlspecialchars(). echo "<form method='post' action='"?><?php echo htmlspecialchars($_SERVER['PHP_SELF']).'?delete=true&recordid='.$doc_folder.'&deletefile='.$file;?> <?php echo"' ><a href='/pages/download.php?file=$file'> $file </a> <input type='submit' value='delete'></form>";And what's with your opening and closing tags? You've gone crazy with them. Quote Link to comment Share on other sites More sharing options...
A JM Posted April 17, 2015 Author Share Posted April 17, 2015 Thanks for the insight and the corrections requinix... I'm still a bit green with PHP, trying to learn as I go. Just greenness on the tags, just wasn't paying attention to it... AJM, Quote Link to comment Share on other sites More sharing options...
Tom10 Posted April 17, 2015 Share Posted April 17, 2015 Sorry about that i'm still learning PHP Quote Link to comment Share on other sites More sharing options...
requinix Posted April 17, 2015 Share Posted April 17, 2015 Nah, I sighed because this question comes up a lot but it's not the easiest thing to Google for. Problem is the symptoms vary, like broken links or losing form data. And just given those symptoms it's not necessarily obvious what's wrong, and the first place you'd check (the PHP code) isn't actually where the true problem is. Just one of those things where you know the answer from experience, not from raw PHP knowledge. Quote Link to comment Share on other sites More sharing options...
A JM Posted April 18, 2015 Author Share Posted April 18, 2015 Many thanks for the help, that resolved the problem. Also, PHP_SELF is not safe to use unless you wrap it in a function like htmlspecialchars(). Can you elaborate on the security issue and how the htmlspecialchars() functions aleviates the problem? AJM, Quote Link to comment Share on other sites More sharing options...
requinix Posted April 18, 2015 Share Posted April 18, 2015 (edited) On 4/17/2015 at 6:00 PM, A JM said: Can you elaborate on the security issue and how the htmlspecialchars() functions aleviates the problem? PHP_SELF contains a portion of the URL that is pretty much exactly as the user entered it in their browser. Most of the time someone can enter in something you didn't expect and still execute your script. For example, "script.php" may be triggered with "script/foo/bar": the web server sees "script", realizes there's a matching file "script.php", and then executes it. Edited August 24, 2018 by requinix removed xss demo because it actually managed to attack this forum XD Quote Link to comment Share on other sites More sharing options...
A JM Posted April 22, 2015 Author Share Posted April 22, 2015 requinex, Having a similar issue after I encapsulated the HTML attributes with quotes... seems like it should be working, thoughts? I'm still seeing the file name get truncated at spaces.. <?php //initialize the session if (!isset($_SESSION)) { session_start(); } $doc_folder= $_SESSION['port_recordID']; //variable comes from detail page only used to carry claimnumber $path = "../claims/" . $doc_folder . "/"; $dir = dir($path); while($file = $dir->read()) { if($file != '.' && $file != '..') { echo "<a href='/pages/download.php?file=$file&recordid=$doc_folder'> $file </a>"; } } ?> Quote Link to comment Share on other sites More sharing options...
A JM Posted April 22, 2015 Author Share Posted April 22, 2015 After further researching - the problem appears to be related to a filename that contains a single quote... I'm not sure how to create the URL to deal with that? 2003 Baja 20' Outlaw.pdf Quote Link to comment Share on other sites More sharing options...
A JM Posted April 22, 2015 Author Share Posted April 22, 2015 (edited) So digging further... ugh. I can accomodate for files with a single quote by using the following: $file = htmlspecialchars($value, ENT_QUOTES); However when the user clicks on the link to download the file the file name now has an "_" underscore in the name, from the GET() function? 2003 Baja 20_' Outlaw.pdf <?php $ID=stripslashes($_GET['recordid']); $file = $_GET['file']; // the absolute path to your directory storing your files. $path = '../claims/' . $ID . '/'; header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Type: application/force-download"); header("Content-Disposition: attachment; filename=\"$file\""); header("Content-Description: File Transfer"); header('Accept-Ranges: bytes'); header('Content-Length: ' . filesize($file)); readfile($path.$file); ?> Edited April 22, 2015 by A JM Quote Link to comment Share on other sites More sharing options...
requinix Posted April 22, 2015 Share Posted April 22, 2015 (edited) $_GET won't do that. Which is an array, by the way, not a function. You need two functions: rawurlencode and htmlspecialchars(). Applied to $file in that order. And htmlspecialchars() alone for the second $file. echo " ", htmlspecialchars($file, ENT_QUOTES), " ";That's because the filename is going into a URL, and you're putting that URL within HTML. When the browser figures out what to do when you click the link, it will HTML-decode the URL first (because it's in HTML) and then verify it is an acceptable URL (and if not, URL-encode it automatically because it's nice like that). In download.php you only look in $_GET: there will be no HTML encoding and the URL decoding happened earlier (since, being in a URL, PHP knew it must necessarily happen at some point anyways). Edited April 22, 2015 by requinix Quote Link to comment Share on other sites More sharing options...
A JM Posted April 22, 2015 Author Share Posted April 22, 2015 (edited) I didn't think to use them together..rawurlencode() or htmspecialcharacters()... duh! I'm still experiencing issues with it though (see attached) The 2nd file, seems to pass correctly to the download but then appears the "_". AJM, EDIT I've tried to break it up like this: $dir = dir($path);while($value = $dir->read()) { if($value != '.' && $value != '..') { $file = htmlspecialchars(rawurlencode($value), ENT_QUOTES); echo "<form method='post' action='"?><?php echo"' ><a href='/pages/download.php?file=$file&recordid=$claim_doc_folder'> $value </a></form>"; }} Edited April 22, 2015 by A JM Quote Link to comment Share on other sites More sharing options...
requinix Posted April 22, 2015 Share Posted April 22, 2015 Not sure what to say. Looks like you're doing everything right and IE is pulling the underscore out of nowhere... It still has the underscore when you save the file, right? Tried another browser? Quote Link to comment Share on other sites More sharing options...
A JM Posted April 23, 2015 Author Share Posted April 23, 2015 It seems to be tied to the down load somehow since the file name looks correct in the URL that is passed. In this cas I tried a simple .jpg that wen clicked is assumed to be a .wav file?? <?php $ID=stripslashes($_GET['recordid']); $file = $_GET['file']; // the absolute path to your directory storing your files. $path = '../claims/' . $ID . '/'; header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Type: application/force-download"); header("Content-Disposition: attachment; filename=\"$file\""); header("Content-Description: File Transfer"); header('Accept-Ranges: bytes'); header('Content-Length: ' . filesize($file)); readfile($path.$file); ?> Quote Link to comment Share on other sites More sharing options...
requinix Posted April 23, 2015 Share Posted April 23, 2015 Your taught your computer that application/force-download type is a "Wave Sound". The thing that triggers the download is the Content-Disposition header, so leave the Content-Type with the right value. Unfortunately that varies by file, and you probably aren't recording it anywhere accessible. You should install something like fileinfo in order to get the type based on the file contents (your only recourse), but if that's not an option, header("Content-Type: application/octet-stream");the application/octet-stream type is your best option because it has an official meaning, unlike application/force-download (which someone simply made up). Quote Link to comment Share on other sites More sharing options...
A JM Posted April 23, 2015 Author Share Posted April 23, 2015 Is there a better way to address file downloads? Maybe a jquery addin or something similar and sort of remove the php coding for the download by passing it the variables of the file, location, etc.? Just trying to remedy the problem with an alternate solution. Thanks for the insight. AJM, Quote Link to comment Share on other sites More sharing options...
CroNiX Posted April 24, 2015 Share Posted April 24, 2015 The best way to address the name issue is to deal with it when the file is UPLOADED. Replace spaces with underscores, remove apostrophes, etc. from the uploaded filename. Then you won't have this issue of having to encode/decode, etc. Personally I'd just use preg_replace and replace anything in the filename that isn't alphanumeric, a period, an underscore or a dash. Quote Link to comment Share on other sites More sharing options...
A JM Posted April 25, 2015 Author Share Posted April 25, 2015 Yes, that is where I ended up since it was becoming difficult to rectify. I've modded the UploadHandler.php in the Jquery_File_Upload plugin its strange that it doesn't deal with those situations already. Many thanks for the input. AJM. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.