This is a bit of a tricky issue to describe, or title. Essentially the issue is this; On a site using the Field Encrypt, I noticed that every so often I would get the one of two errors: Key not found in _encrypt_decrypt() and call_user_func() expects parameter 1 to be a valid callback().

The easiest way in my case to replicate the issues was to drop my db, pull in the production db and run drush uli, but that isn't really something that will help with debugging for others. What I did determine though is that something was invoking a decrypt/encrypt before and after a cache clear, due to the CTools plugin system using require_once was preventing the plugin definition to be loaded in again after the cache had been cleared.

The issue possible lies with CTools to some extent, as any plugin that is used before and after a cache clear would have this issue, but for the moment the issue needs to be dealt with as it could have dire consequences with encrypting/decrypting of data.

The easiest way to resolve this issue, and the way I will be implementing in an upcoming patch, is to implement a function in the pattern of "{MODULE}_{PLUGIN_FILENAME}_{HOOK}" for each plugin (e.g., encrypt_drupal_variable_encrypt_key_providers()) so when the require_once in ctools_plugin_load_includes() fails to read in the plugin definition it will instead defer to the function.

Less than ideal, and I will try to chase it further in CTools, but it's an issue that can be worked around.

CommentFileSizeAuthor
#1 ctools_plugins-2386819-1.patch7.86 KBDeciphered
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Deciphered’s picture

Status: Active » Needs review
FileSize
7.86 KB

Patch attached, implemented the function inside the plugins and referenced the functions for the $plugin value to reduce duplications. Tested and confirmed this works.

I am more inclined to believe this is a CTools issue though, as I have seen this behaviour in my own modules before I just never had the time to truly debug the issue. Regardless, this fix doesn't break anything just makes it extra safe.

rlhawk’s picture

@Deciphered, thanks for the patch. I applied it and everything worked fine with several modules that perform encryption, including Field Encrypt. I didn't have any luck reproducing the issue originally, though. Can you provide a bit more detail about how I might be able to observe it?

rlhawk’s picture

From the documentation in ctools_plugin_load_includes:

// .inc files have a special format for the hook identifier.
// For example, 'foo.inc' in the module 'mogul' using the plugin
// whose hook is named 'borg_type' should have a function named (deep breath)
// mogul_foo_borg_type()
// If, however, the .inc file set the quasi-global $plugin array, we
// can use that and not even call a function. Set the $identifier
// appropriately and ctools_plugin_process() will handle it.

So, I understand that what you're doing is implementing the hook identifier, using the standard CTools format—like "encrypt_default_encrypt_encryption_methods," for instance. If that's the case, why does $plugin need to be assigned by calling the hook identifier? I removed the $plugin assignment from all plugins (after applying your patch) and they continued to work fine. But I'm also confused about what's distinctive about Encrypt that using the hook identifier would even be necessary. I've never seen it used before; for example, in all of Panels, every plugin is assigned directly to $plugin, without a hook identifier.

Deciphered’s picture

I'm unable to provide more reproduction steps as it was on behalf of a client and I'd be required to spend unbillable time digging back through their site to do so. My apologies.

But, I can tell you, based on memory, that the issue was related to the file being included via a CTools 'include_once', when after a cache clear (in the same process) the definition is removed and upon the second invocation due to the 'include_once' the file could not be included again and the definition could not be populated again. I've actually seen the issue before in other modules. It's more likely a CTools issue.

The reason I implemented it as I did is that it uses both available methods with the least amount of duplication making it as compatible as possible. However you're welcome to take which ever approach you wish, but I would urge you to go with the hook based approach for the flaw with the 'include_once' approach I have outlined.

Dave Reid’s picture

I'm also able to reproduce just using a very basic SimpleTest that enables the encrypt module in setUp(). The first test method works just fine, but the second method for some reason fails to include drupal_private_key.inc and hence fails to use the default encryption and decryption method.

With the patch applied things work great.

rlhawk’s picture

Status: Needs review » Reviewed & tested by the community

Marking as RTBTC.

  • rlhawk committed 644dedb on 7.x-2.x authored by Deciphered
    Issue #2386819 by Deciphered: Encrypt/Decrypt and cache clear issue with...
rlhawk’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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

Elijah Lynn’s picture

Issue summary: View changes