Some times, quite randomly, the $data and $options variables are not set (not accessible in the token php snippet).
And this error message might be returned:

Parse error: syntax error, unexpected T_STRING in /var/www/dev/mlegaignoux/projectaegis/modules/php/php.module(74) : eval()'d code on line 3

I traced it back to the function token_custom_token_render().

The syntax error on line 3 comes from the code prepended to the token code.

$code = '
  if ($static = drupal_static(\'' . $static_key . '\')) {
  } ?>' . $code;

(please look at the original source code for reference. I can't get the quotes to show up correctly)

But as you can see there is not syntax error here. Or at least... not yet.
Because if $static_key contains a quote (') for example... we obviously have a syntax error.

And we have this a few lines before:
$static_key = 'token_custom_' . drupal_random_bytes(10);

So, a solution is to base64 encode it (because not only quotes causes problems).
$static_key = 'token_custom_' . base64_encode(drupal_random_bytes(10));

We can also completely replace drupal_random_bytes by something else I guess.
Or we could even avoid using drupal_static.
I don't really know, I'm new to drupal, but it seems like a strange way to use drupal_static.
And this random thing is not a 100% safe.

I'll try to submit a patch after more testing.


gaspaio’s picture

Priority:Normal» Major

I agree with everything you say, this really needs work & testing i gess.
It was the only thing i could think of to pass the variables onto the php snippet.
Patches are welcome indeed. Thanks.

aldrup’s picture

Status:Active» Needs review
new568 bytes

I've been looking more closely at the module and it seems that drupal_static is a fine way to pass the variables.
I couldn't think of better ways to do it either. So, let's keep it like this.

Concerning the issue:

How to reproduce the bug:
Create a custom token and select the "PHP code" text format.
(What your token does doesn't matter, you can leave it empty)
Navigate to /devel/php (you need the devel module) and copy/paste the following code 10 times or more.
print token_replace('[custom:test]');
(don't forget to change the token name)

Execute until you see some Warnings, Parse error, etc.

The patch:
I was looking for a replacement to drupal_random_byte. It had to produce a "safe" and random string efficiently.
I found the perfect candidate in includes/
$session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));

And all we need is:
uniqid(mt_rand(), TRUE);
(I believe we have enough entropy there)

So here is the patch:

zhangtaihao’s picture

new1.35 KB

If all you want is to prevent nested tokens from interfering with each other's data, you'd really just maintain a stack.

zhangtaihao’s picture

new1.02 KB

Sorry, my patch in #3 didn't quite work. The markup was cached by check_markup().

Then again, a simple counter would work.

covenantd’s picture

Patch in #2 did the trick for us. #4 looks like it would work too though so just a question of ideal approach here.

zhangtaihao’s picture

The issue with drupal_random_bytes() is that it literally returns bytes (i.e. non-text). So, yes, #2 works because it gets a text string. Nonetheless, given this isn't meant to account for massive randomness (like form ids), even uniqid(mt_rand(), TRUE) seems an unnecessary use of resources, IMHO.

peterx’s picture

#4 works for me. If you are creating the static entry then destroying it after use, as in #4, there is no need for a unique name.

adelka’s picture

4# works for me also :)

zhangtaihao’s picture

Status:Needs review» Reviewed & tested by the community
bago’s picture

+1 for #4

gaspaio’s picture

Status:Reviewed & tested by the community» Fixed

Thanks a lot for the patch and reviews :-).

Status:Fixed» Closed (fixed)

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

derek.deraps’s picture

Status:Needs review» Closed (fixed)

Is anyone else, like me, still experiencing this issue even in the latest release (7.x-2.0-beta3)? The code in the patch given here is indeed committed to the latest release, but $data and $options are still not available to my custom token.

If it's helpful, here's what get_defined_vars() tells me is available:

  • code (string)
  • theme_path (string)
  • theme_info (object)
  • conf (array)
  • old_theme_path (string)

Shall I open a new issue?

derek.deraps’s picture

Issue summary:View changes

failed to fix quoted code...

derek.deraps’s picture

Status:Closed (fixed)» Needs review

Status:Closed (fixed)» Needs review