Problem

If using drush en modulename and drush needs to download said module and also the module install uses drupal_get_path to load the module, then this call fails. Because drupal_get_filename() does not search the filesystem if the database {system} table does not contain the entry despite the function contains the code for this case.

Steps to reproduce:

  • place new module/theme folder anywhere they should be;
  • execute return drupal_get_filename($type, $name) with appropriate arguments in drush or /devel/php.

Expected to get a filepath to .info or .module file.

Instead got (Boolean) FALSE.

Proposed resolution

Either:

  1. additional check what db_query() returns;
  2. do check with empty($files[$type][$name]) instead of !isset() when going to fallback.

Remaining tasks

CommentFileSizeAuthor
#2 D7-2228825-2-drupal_get_filename.patch628 bytesdonquixote
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

donquixote’s picture

Oh-oh.
Just ran into this myself.
This needs some more attention!

donquixote’s picture

Status: Active » Needs review
FileSize
628 bytes

Starting with the most basic/naive approach.

donquixote’s picture

When does this happen in "the real world" ?

One example is "drush en -y MODULENAME", if
- the respective module is not downloaded yet, so drush will auto-download it, AND
- the respective module calls e.g. MYMODULE_foo() from within hook_install(), and this is defined in the MYMODULE.module file (which is not included yet).

I ran into this with xautoload, which gave me
PHP Fatal error: Call to undefined function xautoload() in [..]/sites/all/modules/contrib/xautoload/xautoload.install on line 14
function xautoload() is in xautoload.module.

Alternatively to freshly downloading, it is enough to simply wipe the database before installing:
drush dis -y xautoload; drush pm-uninstall -y xautoload; drush sqlq "delete from system where name = 'xautoload';"; drush en -y xautoload;
(this is with xautoload-7.x-5.0. I might publish a new release that explicitly calls require_once xautoload.module from xautoload.install, so this would not happen anymore)

In most other situations, the respective module will already be in the database from a previous request, so this all won't happen.
But even if nothing bad happens, this is pure coincidence. The code here is definitely flawed.

donquixote’s picture

I also want to add that this bug is hard to reproduce, if you don't know what you are looking for.
Usually after the bug occured once, the database will be intialized with the new module, and so you won't see it again. It will be as if it never happened. (but it could be that some installation step went wrong due to this).

This could be one reason why this was not reported more often.

chx’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

I like this solution more because it saves a bogus file exists call.

David_Rothstein’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 7.x - thanks!

  • David_Rothstein committed c95d725 on 7.x
    Issue #2228825 by donquixote | pingwin4eg: Fixed drupal_get_filename()...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

jeroen.b’s picture

Be aware that this could really kill your site. If you have any typo's in module_load_include (like imagecache had), it will do a recursive file_scan_directory on every page request.

Imagecache has this:
module_load_include('inc', 'imagcache_actions', 'image_overlay.inc');

While < 7.33, this was no problem, as file_exists(DRUPAL_ROOT . '/' . $file) is true when $file is empty, but >= 7.33, it will go into another routine to do a file lookup as there is another check.

This one was a pain to find, so I hope I help anybody by writing this up.

pingwin4eg’s picture

@jeroen.b so this is a bug of imagecache_actions module. And that issue was fixed almost a year ago (#2166715: Typo causes extra query every page load).

jeroen.b’s picture

@pingwin4eg
It is a bug of the imagecache_actions module, it's fixed in dev, but still not released into stable.

However, it's a pain to find this problem when you experience it (it's not like this can only happen at imagecache_actions). Maybe we should log it into watchdog when it can't find the file in the registry?

joelpittet’s picture

Maybe we should log it into watchdog when it can't find the file in the registry?

Would you mind writing a patch for that @jeroen.b? We can open up a follow-up to tackle that task.

jeroen.b’s picture

@joelpittet, I'll have to check to see if watchdog is always available at that point.
I think I can have something ready tomorrow.

jeroen.b’s picture

@joelpittet, patch and further discussion in #2380361

joelpittet’s picture