Allowing uploads of all file types in Drupal

I just switched the site over from b2evolution to Drupal. In migrating posts I needed to attach some javascript files to a blog-entry. As a security measure Drupal renames files with executable extensions "php|pl|py|cgi|asp|js", appending an underscore and a ".TXT" extension. That's reasonable. What's odd is that there is no setting to provide an override, either to specific users, or site-wide.

My initial question asking if there was a setting to override this security feature met with limited response, so a bit of research later here's what I came up with.


Mainly what I found out is that this is a three-year old issue! Also, that we need to patch the core in order to prevent files being renamed and having .TXT appended. Nice. This is painful because it's not obvious to new users why some files have .TXT appended to them, nor is it obvious how to work around this in cases where they may want to do that. The need for this behavior, enabled by default is obvious. But having a permission to override when needed seems like a no brainer. I don't understand why this seems to have been patched numerous times, from 2005 to 2008, and still isn't in the core. Go figure.

Future Reference

For anyone in the future:

  • this patch #144760 seems to be the most recent, but I'm not sure how to find a specific patch associated with an issue. In the meantime I made my own patch, below.
  • The comment in #41561 is no longer valid -- the module no longer exists. However, file.inc seems to be filtering "php|pl|py|cgi|asp|js" and applying the .txt extension, which gave me a clue for my patch below.

A Workaround Patch

So using the technique from a post dating from 2005(!!!), I made the changes below.

Note that I suspect you should not make these changes to the core files but I'm not yet sure how to make fine-grained (sub-function level) alterations to the core, so buyer-beware.

  1. Add a new upload permission: In the modules directory find the file upload.module, locate upload_perm() and add an extra permission 'upload any filetype':
    function upload_perm() {
      return array('upload files', 'view uploaded files', 'upload any filetype');
    }
    
    
  2. Allow roles with 'upload any filetype' to upload any filetypes: In the includes directory find the file file.inc, locate file_save_upload() and at line 533 (as of 6.2) change from:
     
        if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
    
    
    ...to this, adding the 'upload any filetype' condition at the end:
     
        if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt') && (!user_access('upload any filetype')) ) {
    
    
  3. Assign the permission:You can now navigate through your admin panel to admin/user/permissions and grant this permission to one or more roles.

That's it. Hope someone else finds this useful.

Comments

  1. By Tim, on March 02, 2011, at 11:22 PM
    Thank you, this helped me! I wanted to upload sample py files to my class website and it was annoying that they got the .txt extension. Just as a tip from 2005 helped you, your tip from 2008 helped me in 2011!
  2. By daveg, on March 12, 2011, at 10:38 AM
    Glad it's still helping!
  3. By Nils von Barth, on June 10, 2011, at 01:23 PM
    Thanks for the great write-up