When the file download method is set to Private, files containg a "+" in their filename cannot be downloaded.

Drupals url() function incorrectly translates a "+" in a the filename to a space, this causes the file to not be found on the file system and in turn causes file_transfer() to return a 404.

When the download method is set to public, the same file can be downloaded without any problems.

I've had a half-hearted attempt at a patch that uses rawurlencode() to encode the filename passed to the url() function, but that causes the file that is to be saved to contain a "%2B" instead of a "+" when the download method is Public.

Comments

Assigned:Unassigned» mikeparker

Hi, I'll have a look into this problem and see what I can find.

Assigned:mikeparker» Unassigned
Status:Active» Needs work

Having replicated the problem on a test system, I worked back from the url on the page.

Everything's fine in the database and file system (so, that's not where the problem is). When I got to the call to url() in file.inc, I got the same error returning a string with a + in it as I did calling the url function. (So, it doesn't look like it's the url function causing the bug).

I worked back to modules/upload/upload.module and the function theme_upload_attachments() which sets $href by calling file_create_url(), (using the url() function).

replacing $href with some dummy urls, containing a '+', the problem still comes up.

So the conclusion is that the code that's calling theme_upload_attachments from upload.module seems to be formatting the url incorrectly.

I suspect it assumes a + is an encoded space and will treat it as such, so by the time the browser requests the file, it effectively asks for "This file name.pdf" rather than "This%2Bfile%2Bname.pdf".

I'm pretty sure I've worked around it by asking my client to not upload files with a + in their name and I'm also pretty sure I enabled transliteration on the filename.