A lot of modules implement this hook and return false when they don't explicitly allow the download of the provided file. However, returning false instead of nothing or an empty array will result in an entry in the $headers array created by module_invoke_all('file_download', $filepath).
An because of this the file will be allowed to be downloaded even if no module explicitly allowed it.

Example:

The following hook implementation will allow all files to be downloaded

function mymod_file_download($fp)
{
  return false;
}

The following two won't:

function mymod_file_download($fp)
{
  return;
}
function mymod_file_download($fp)
{
  return array();
}

There are various ways to fix it, either change module_invoke_all not to merge false into the result, or modify the count($headers) check to check for valid headers in the file.inc or let all modules that implement hook_file_download to properly return;

Comments

samc’s picture

In case this helps someone, Flexinode is a known offender. A patch is in the works:

http://drupal.org/node/64573

Bèr Kessels’s picture

"offender" is relative. I beleive strong in consistent return values. Sot "FALSE or a string" is something I beleive is bad coding style.

Fixing this in core will allow flexinode to return proper values :)

magico’s picture

Version: 4.7.3 » 4.7.5
Status: Active » Fixed

According to the documentation this is not a bug (and modules should follow this)

If the user does not have permission to access the file, return -1. If the user has permission, return an array with the appropriate headers.

Anonymous’s picture

Status: Fixed » Closed (fixed)