i’ve seen the same problem, and it’s frustrating!
we often scan and upload a picture and repeat, because it needed correcting. it’s when you repeat that the file is overwritten because there is a case where wordpress can’t tell that you have already uploaded the file and overwrites it.
to repeat the problem you need:
1. a file system with case sensitive file names – ie ext3, not mac os x’s hfs.
2. to upload a file with Upper case characters twice.
3. wordpress 2.3 and above (the trunk version still has the same problem)
in our case we’re using wordpress 2.3.3 with the plugin yet-another-photo-blog. yet-another-photo-blog delegates the uploading to wordpress and it is wordpress that overwrites the file. yet-another-photo-blog makes it worse afterwards because it attempts to remove the previous image, which due to the overwriting, is actually the new image. you can’t fix that one without putting the file back manually.
the problem code seems to be in wp-admin/includes/file.php::wp_handle_upload
for wordpress 2.3.3, while in the trunk it was moved (but not fixed) to wp-includes/functions.php::wp_unique_filename
.
here is a snippet of the existing code:
$number = '';
$filename = str_replace( '#', '_', $file['name'] );
$filename = str_replace( array( '\\', "'" ), '', $filename );
if ( empty( $ext) )
$ext = '';
else
$ext = ".$ext";
while ( file_exists( $uploads['path'] . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
$filename = str_replace( $ext, '', $filename );
$filename = sanitize_title_with_dashes( $filename ) . $ext;
the issue is that the code searches for a unique file name using the test file_exists
and then after finding a unique file name, it goes and changes the name using the method sanitize_title_with_dashes
to one, that is not unique. oops. this is tricky because the method does stuff like convert all the letters to lower case, which on some filesystems doesn’t affect the uniqueness of the file. but on unix-like filesystems it does.
so here’s what happens:
user uploads PICTURE.jpeg
wordpress searches for PICTURE.jpeg
wordpress does not find it
wordpress renames PICTURE.jpeg to picture.jpeg
wordpress saves the file picture.jpeg
and then..
user uploads PICTURE.jpeg
wordpress searches for PICTURE.jpeg
wordpress does not find it (because the letters are different cases)
wordpress renames PICTURE.jpeg to picture.jpeg
wordpress overwrites picture.jpeg
i have implemented a quick fix in our site by moving the last two lines to before the unique tests.
$number = '';
$filename = str_replace( '#', '_', $file['name'] );
$filename = str_replace( array( '\\', "'" ), '', $filename );
if ( empty( $ext) )
$ext = '';
else
$ext = ".$ext";
$filename = str_replace( $ext, '', $filename );
$filename = sanitize_title_with_dashes( $filename ) . $ext;
while ( file_exists( $uploads['path'] . "/$filename" ) ) {
if ( '' == "$number$ext" )
$filename = $filename . ++$number . $ext;
else
$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
}
so the important thing here is that the file_exists
test happens every time after the filename is changed. this will prevent wordpress from overwriting our important files! anyone want to fix this?