Link to home
Start Free TrialLog in
Avatar of hibbsusan
hibbsusan

asked on

backslashes preventing file transfer

I have files that have been uploaded to a folder on my site, but the upload software I have been using adds backslashes to apostrophes.

This makes the SuperFlexibleFileSynchronizer i use unable to transfer the files. I thought about using rawurlencode to change all of these non-alphanumeric characters to code, which makes the file synchronizer able to transfer them, but the local FTP site I am transferring them to now has encoded file names. Is there anyway I can put a piece of software on the FTP site to decode the file names?

Has anyone got any suggestions?

Thank you so much!
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

You might be able to use stripslashes() to correct the escape characters.
http://php.net/manual/en/function.stripslashes.php
Avatar of Rob
Or remove the apostrophes from the files brier you uploa them.
Avatar of hibbsusan
hibbsusan

ASKER

i just cannot understand where in the uploader script the slashes are being added. The php.php document has no addslashes() function that I can see. It does have ENT_NOQUOTES in line 165. I don't really understand what it does though..
It's not the javascript uploader or php that's doing this, it's the operating system.  I have tested this on Windows using IIS and it doesn't change the apostrophe.  I've tested on Linux and it adds the apostrophe.

This narrows it down and I'm thinking you could get this question re-zoned into the linux, shell scripting area??
I guess we're at the point where I ask "Why do your files have apostrophes anyway?" :)
Agree with tagit -- file names with apostrophes in them are a recipe for all kinds of trouble.  I would stick to letters, numbers and underscores.  Experience says these will always work correctly.

If you run this script:

<?php phpinfo();

... You may be able to see whether PHP has "magic quotes" set to "on" on the Linux machine.  Check these links.

http://us2.php.net/manual/en/security.magicquotes.whynot.php
http://us2.php.net/manual/en/security.magicquotes.disabling.php
Great suggestion Ray as I've tested with FTP and echo etc in the terminal and you can create filenames with apostrophes (just to rule it out!)

In other words it's definitely PHP causing this "problem".
with php info I see

directive               local    master
magic_quotes_gpc	On       On
magic_quotes_runtime	Off	 Off
magic_quotes_sybase	Off	 Off

Open in new window


I agree that file names with quotes are sort of a pain. Is there any built-in php function or regular expression I can use to strip things down to alphanumeric only?

thank you guys!
well gpc is GET/POST/COOKIE operations as it says in the manual about magic_quotes_gpc:

Sets the magic_quotes state for GPC (Get/Post/Cookie) operations. When magic_quotes are on, all ' (single-quote), " (double quote), \ (backslash) and NUL's are escaped with a backslash automatically.

so turning them off as Ray has suggested should do the trick but in terms of stripping down to alphanumeric, you will need to go through your file system and do this.  

You could get PHP to do this, but it's easier to use a batch file (powershell, bat, vbs - windows) or shell script (linux).
I'd prefer just to do it with php just so I don't have to deal with another entire script. Is it totally unfeasible?

Thanks
sure.  This is from the user contributed notes on the php manual

http://php.net/manual/en/function.scandir.php#96326
I don't really understand this :(

I mean, is there a function I can call to strip a variable of all non-alphanumeric characters.

like $filename = stripNonAlphaNumericCharacters($filename)

??
Sorry I didn't have time to modify the function for you but essentially for every file found, test if it contains illegal chars such as apostrophe and rename it with it removed. I'll post some sample code soon
here is the full code
<?php
/**
 * Calls a function for every file in a folder.
 *
 * @author Vasil Rangelov a.k.a. boen_robot
 *
 * @param string $callback The function to call. It must accept one argument that is a relative filepath of the file.
 * @param string $dir The directory to traverse.
 * @param array $types The file types to call the function for. Leave as NULL to match all types.
 * @param bool $recursive Whether to list subfolders as well.
 * @param string $baseDir String to append at the beginning of every filepath that the callback will receive.
 */
function dir_walk($callback, $dir, $types = null, $recursive = false, $baseDir = '') {
    if ($dh = opendir($dir)) {
        while (($file = readdir($dh)) !== false) {
            if ($file === '.' || $file === '..') {
                continue;
            }
            if (is_file($dir . $file)) {
                if (is_array($types)) {
                    if (!in_array(strtolower(pathinfo($dir . $file, PATHINFO_EXTENSION)), $types, true)) {
                        continue;
                    }
                }
                $callback($dir,$file);
            } elseif ($recursive && is_dir($dir . $file)) {
                dir_walk($callback, $dir . $file . DIRECTORY_SEPARATOR, $types, $recursive, $baseDir . $file . DIRECTORY_SEPARATOR);
            }
        }
        closedir($dh);
    }
}

function CheckFileName($dir, $file) {
	// check that the filename doesn't contain an apostrophe
	
	$new_file = $str_replace("'", "", $file);
	
	// no unnecessary renaming of files
	if (strcmp($new_file,$file)<>0) {
		// rename the file
		rename($dir . $file, $dir . $new_file);
	}
}


dir_walk(CheckFileName, ".", null, true);

?>

Open in new window

I'm sorry I'm being so thick! But I don't understand where to implement this :(

Should it go in the code to change the filename before it's uploaded? Can you please explain a bit more?

Sorry :(
ASKER CERTIFIED SOLUTION
Avatar of Rob
Rob
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I turned off the magic quotes. Would I still use your script? And where? And how to run it, or keep it constantly running?

Thanks
Ok so what you've done is allowed these characters to be on your filenames.
As for my script. I'd imagine you'd run it once from the comand line and then all you have to do is not create file names with illegal characters :)
I've been out of town for a while and I'm not sure where you are on this problem.  But regarding this,

$filename = stripNonAlphaNumericCharacters($filename)

The code snippet should probably be tested to see if it meets your needs.  On my server here:
http://www.laprbass.com/RAY_temp_hibbsusan.php
<?php // RAY_temp_hibbsusan.php
error_reporting(E_ALL);


// NEED A FUNCTION LIKE THIS
// $filename = stripNonAlphaNumericCharacters($filename)


function stripNonAlphaNumericCharacters($string, $plug='_')
{
    // A REGULAR EXPRESSION
    $regex
    = '#'                 // REGEX START DELIMITER
    . '['                 // CHARACTER CLASS DELIMITER
    . '^'                 // NEGATION - MATCH NONE OF THESE
    . 'A-Z0-9_.'          // LETTERS, NUMBERS, UNDERSCORE, DOT
    . DIRECTORY_SEPARATOR // CONTEXT-AWARE CONSTANT FOR THE SLASH
    . ']'                 // CLOSING CHARACTER CLASS DELIMITER
    . '#'                 // REGEX ENDED DELIMITER
    . 'i'                 // CASE INSENSITIVE
    ;
    // SEE http://php.net/manual/en/function.preg-replace.php
    return preg_replace($regex, $plug, $string);
}



// SOME TEST DATA
$filenames = array
( 'ThisIsAGoodName.jpg'
, 'This has blanks.png'
, "This one's not so Good.gif"
, 'path/to/but_this_is_ok.bmp'
)
;



// TEST THE REGULAR EXPRESSION
foreach ($filenames as $f)
{
    // TRANSFORM THE FILE PATH
    $g = stripNonAlphaNumericCharacters($f);

    // SHOW THE WORK PRODUCT
    echo '<br/>';
    echo $f;
    echo ' BECOMES ';
    echo $g;
    echo PHP_EOL;
}

Open in new window

Your help was outstanding. Thank you!

I'm so sorry I forgot to assign the points.

Thanks again!