:: in .info files causes Fatal error

ExTexan - April 5, 2009 - 15:21
Project:Drupal
Version:6.x-dev
Component:base system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:needs review
Description

Following the very detailed (and very helpful) instructions for creating a new sub-theme for Zen, I got down to modifying the .info file (mine is litdep.info). I changed the breadcrumb separator as follows:

settings[zen_breadcrumb_separator] = ' :: '

When I refreshed my front page, I got the following error:

Fatal error: Class ' ' not found in C:\Users\Doug\Webs\Drupal-Test\includes\common.inc on line 3551

Changing the separator back to ">" fixed the error.

#1

JohnAlbin - April 30, 2009 - 13:38
Category:bug report» support request
Status:active» fixed

Yes, that’s very annoying. The syntax of the .info file doesn’t allow you to put a :: in it. :-( [edit: this is a bug in Drupal core.]

Fortunately, there's a workaround. Use an HTML escape sequence for the semi-colon, :

settings[zen_breadcrumb_separator] = ' :: '

#2

System Message - May 14, 2009 - 14:00
Status:fixed» closed

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

#3

ExTexan - May 15, 2009 - 00:15
Status:closed» needs work

Why do issues automatically close? Seems to me they should only be closed manually when a solution is found and implemented.

#4

JohnAlbin - May 15, 2009 - 09:11
Status:needs work» closed

ExTexan, issues are automatically moved from "fixed" to "closed" after 2 weeks of inactivity. "Fixed" issues remain in the list of open issues so that other users can more easily see them, but "closed" ones can still be searched for.

I marked this issue "fixed" in comment #1 because I provided the solution.

#5

ExTexan - May 16, 2009 - 01:54
Status:closed» needs work

Yes, I understand that you provided a "work-around". But even so, I don't think something should remain in Drupal if it can crash the site as hard as this "bug" does. As I recall, the error message when it crashed wasn't even all that helpful in determining the cause. I had to spend way too much time retracing what I had done in order to pinpoint the cause.

If you can put forth a valid argument as to why an issue that crashes Drupal should be "closed", then I'm all ears.

#6

JohnAlbin - May 17, 2009 - 19:30
Title:Double-colon Breadcrumb Separator causing fatal error» :: in .info files causes Fatal error
Project:Zen» Drupal
Version:6.x-1.0» 7.x-dev
Component:Miscellaneous» base system
Category:support request» bug report
Status:needs work» active

I meant it wasn't a bug in Zen. But I'm happy to move it over to the main Drupal core issue queue.

Because it means having to re-write the way .info files are formatted, it won't ever be fixed in D6. And D7's code freeze is on Sept 1.

#7

ExTexan - May 18, 2009 - 04:13

I see. Thanks for the clarification (Zen vs Drupal core). That makes sense. Hard to believe such a minor thing could cause such a hard failure in Drupal. Thanks for moving the issue to the proper place.

Cheers...

#8

mr.baileys - May 18, 2009 - 09:00
Status:active» needs review

Looks like the issue occurs during this call in common.inc (while parsing the .info files), where Drupal checks to see if any of the values in the .info file might be constants:

<?php
// Handle PHP constants
if (defined($value)) {
 
$value = constant($value);
}
?>

Since PHP 5, the 'defined'-function can be used for class constants as well as 'normal' constants, and when it encounters '::' it expects a class + constant (it will also return a fatal error in case the class exists but the constant doesn't).

Attached is a patch that fixes this bug. Longer term, maybe we should consider using token replacements or something similar for the PHP constant replacements in the .info files.

The patch fetches a list of defined constants and checks against that list instead of using the 'defined' function. Besides no longer throwing fatal errors, some rudimentary tests show that this is about 40% faster than using defined (confirmation).

AttachmentSizeStatusTest resultOperations
424372-double-colon-info.patch1.76 KBIdleFailed: Failed to apply patch.View details | Re-test

#13

chx - May 18, 2009 - 17:53

Following some issue cleanup, I like the patch, but a) please use isset not array_key_exists b) write a test. I would write a test module and a text file and then var_exports the results of the parse into an unthemed page. The reason for this would be that fatal errors should not be tested in the process space of the parent Drupal but in the child.

#14

ExTexan - May 19, 2009 - 02:35

Thanks chx for the info on 7.x. Sorry to say though, I don't really understand this:

I would write a test module and a text file and then var_exports the results of the parse into an unthemed page. The reason for this would be that fatal errors should not be tested in the process space of the parent Drupal but in the child.

Can you elaborate (in newbie terms)? Thanks.

#15

chx - May 19, 2009 - 03:24

ExTexan, I already unpublished several comments of yours on this issue. If you want to learn Drupal coding and test writing, I am eager to help you on IRC but not in this issue.

#16

mr.baileys - May 19, 2009 - 07:44

New patch attached:

  • Changed array_key_exists to isset. Note that the result of array_key_exists and isset will differ for a constant set to NULL. Array_key_exists would return TRUE for a constant that is set to NULL, isset will return FALSE for the same constant. Is this an issue?
  • Added a test that verifies that '::' does not throw a fatal error, that the value is parsed correctly, and that constant values still work.

The test was built according to chx's guidance (#13 and IRC). I originally used eval to parse the output of 'common-test/drupal-parse-info-file' back to a PHP variable, but using eval proved to be to cumbersome (and it can still take down the parent Drupal instance), not to mention that it's probably bad practice to use it anyway, so I've settled for plain text assertions instead...

AttachmentSizeStatusTest resultOperations
424372-double-colon-info-3.patch5.73 KBIdleFailed: Failed to apply patch.View details | Re-test

#17

mr.baileys - May 19, 2009 - 08:01

Follow-up patch after talking to chx on IRC:

  • Renamed the .info test file to .txt to make sure it won't be picked up as a genuine .info file;
  • Used assertRaw instead of assertText;
  • Removed print_r as var_export outputs by default.
AttachmentSizeStatusTest resultOperations
424372-double-colon-info-4.patch5.67 KBIdleFailed: Failed to apply patch.View details | Re-test

#18

chx - May 19, 2009 - 13:53

Almost ready, but +class ParseInfoFilesTestCase extends DrupalWebTestCase { needs a doxygen.

#19

mr.baileys - May 19, 2009 - 20:06

Now with additional Doxygen thingy :)

AttachmentSizeStatusTest resultOperations
424372-double-colon-info-5.patch5.76 KBIdleFailed: Failed to apply patch.View details | Re-test

#20

chx - May 20, 2009 - 03:59

I am so sorry for not catching this before but + $this->assertRaw("'simple_constant' => 6", t('Constant value was parsed correctly.'), t('System'));
this should use the constant instead of its value I think. "'simple_constant' => ". WATCHDOG_INFO

#21

mr.baileys - May 20, 2009 - 07:49

No problem at all. I choose WATCHDOG_INFO to have a constant that would be around for a long time and doesn't change much over time, but it didn't occur to me to include the same constant in the assertion. Doh.

New patch attached...

AttachmentSizeStatusTest resultOperations
424372-double-colon-info-6.patch5.77 KBIdleFailed: Failed to apply patch.View details | Re-test

#22

chx - May 22, 2009 - 03:11
Status:needs review» reviewed & tested by the community

I like this patch very much. Is this our first fatal error testing? I think it is.

#23

webchick - May 22, 2009 - 07:45
Status:reviewed & tested by the community» needs review

Hm. Can I ask why an entire module with a menu callback was created for this, rather than just checking the results of drupal_get_path('module', 'simpletest') . '/tests/common_test_info.txt'); directly in the assertions?

(Hint: that means we need to document why that is, if it's intended ;))

#24

mr.baileys - May 22, 2009 - 08:04

You can certainly ask :). I wondered about documentating this, but I have to admit that I don't know how to best phrase this... It boils down to something like this:

The extra module is necessary since a failed test might throw a fatal exception, halting further test processing. By moving it to its own module, the fatal error (if it occurs) is thrown in the child process instead of in the parent (testrunner) process, and it can be detected and handled cleanly without hindering other tests.

Here's chx's earlier quote describing the need for a separate module:

I would write a test module and a text file and then var_exports the results of the parse into an unthemed page. The reason for this would be that fatal errors should not be tested in the process space of the parent Drupal but in the child.

I think this way of working is similar to what is used in #469768: PASS.

#25

mr.baileys - May 22, 2009 - 08:54

Would this be ok as documentation at the start of common_test.module:

/**
* @file
* A test module to assist in testing common.inc.
* This module can be used whenever a test might potentially throw a fatal error. By
* moving those tests to this module, errors are generated in the child process and
* cannot hinder the overall (parent) test process.
*/

#26

System Message - May 25, 2009 - 11:46
Status:needs review» needs work

The last submitted patch failed testing.

#27

mr.baileys - June 3, 2009 - 12:17
Status:needs work» needs review

Re-rolled after changes to HEAD, and incorporated some documentation into common_test.module to explain the reasoning behind the use of a separate module.

AttachmentSizeStatusTest resultOperations
424372-double-colon-info-7.patch4.97 KBIdleFailed: Failed to install HEAD.View details | Re-test

#28

System Message - June 5, 2009 - 20:37
Status:needs review» needs work

The last submitted patch failed testing.

#29

chx - June 6, 2009 - 14:25
Status:needs work» needs review

#30

catch - June 7, 2009 - 10:08
Status:needs review» needs work

The new comments look better. Couple of minor code style things:

+ * @file
+ * A test module to assist in testing common.inc.
+ * This module can be used whenever a test might potentially throw a fatal error. By

Should probably be a line break between the first line and the rest of the description.

+
+/**
+ * Implementation of hook_menu().

This is now "Implement hook_menu() in core.

#31

mr.baileys - June 8, 2009 - 06:47
Status:needs work» needs review

Thanks, new patch attached with the code style changes mentioned in #30.

AttachmentSizeStatusTest resultOperations
424372-double-colon-info-8.patch4.97 KBIdleFailed: Failed to install HEAD.View details | Re-test

#32

catch - June 8, 2009 - 08:34
Status:needs review» reviewed & tested by the community

Looks good now, back to RTBC.

#33

Dries - June 9, 2009 - 11:13

I'm not sure I understand why we create a new module for this. There is a lot of code that can throw fatal errors, and when that happens, we need to debug it either way. We improved reporting of fatal errors so this should be reasonably easy to do. Still feels like overkill to me.

#34

System Message - June 13, 2009 - 13:01
Status:reviewed & tested by the community» needs work

The last submitted patch failed testing.

#35

lilou - June 13, 2009 - 13:52
Status:needs work» reviewed & tested by the community

Setting to RTBC - testbot was broken.

#36

Dries - June 13, 2009 - 19:32
Status:reviewed & tested by the community» needs review

Setting to 'needs review' because of #33. I'm not convinced this is the proper approach.

#37

System Message - June 24, 2009 - 01:25
Status:needs review» needs work

The last submitted patch failed testing.

#38

mr.baileys - September 28, 2009 - 14:39
Status:needs work» needs review

Re-rolled. Dropped the extra module all-together in favor of just a unit test.

AttachmentSizeStatusTest resultOperations
424372-double-colon-info-38.patch6.15 KBIdleFailed: Failed to apply patch.View details | Re-test

#39

System Message - September 30, 2009 - 15:10
Status:needs review» needs work

The last submitted patch failed testing.

#40

Eric At NRD - October 14, 2009 - 02:26

subscribing -- after submitting a duplicate issue in http://drupal.org/node/430166

#41

boombatower - November 11, 2009 - 00:12
Status:needs work» reviewed & tested by the community

This just killed contrib testing, lets get this in, eh? Re-roll and confirmation it worked on d6.

AttachmentSizeStatusTest resultOperations
424372-double-colon-info.patch2.94 KBIdlePassed: 14685 passes, 0 fails, 0 exceptionsView details | Re-test

#42

boombatower - November 11, 2009 - 00:16

Stripped t() from getInfo().

AttachmentSizeStatusTest resultOperations
424372-double-colon-info.patch2.93 KBIdlePassed: 14678 passes, 0 fails, 0 exceptionsView details | Re-test

#43

boombatower - November 11, 2009 - 00:18

D6 patch.

AttachmentSizeStatusTest resultOperations
424372-double-colon-info-D6.patch762 bytesIgnoredNoneNone

#44

webchick - November 11, 2009 - 00:49
Version:7.x-dev» 6.x-dev

Cool. This approach makes a lot more sense than adding the overhead of a new module. And we can extend this tests in the text file to put other things that might break the .info file parser in the future.

Committed to HEAD! Thanks!

Marking back down to 6.x.

#45

Gábor Hojtsy - December 7, 2009 - 16:04
Version:6.x-dev» 7.x-dev
Status:reviewed & tested by the community» needs work

I'm not getting why we invoke constant() when we already have the value of the constant in an array key. Looks to be no reason for that.

#46

mr.baileys - December 8, 2009 - 12:37
Status:needs work» needs review

@Gabor:

The original issue was defined() choking on keys with double colons in them, so the "check to see if we're dealing with a constant"-logic was altered, the rest (including actually loading the value of the constant) was left untouched.

From a DX perspective I actually prefer the current solution, performance-wise it looks like re-using the array is 2-3 times faster compared to loading the value via constant().

I don't really care whether we replace constant() or leave it in place... Patch attached in case looking up the value in the array is prefered over the use of the function.

AttachmentSizeStatusTest resultOperations
424372-double-colon-in-info-D7.patch519 bytesIdlePassed on all environments.View details | Re-test

#47

Arancaytar - January 3, 2010 - 09:05
Status:needs review» reviewed & tested by the community

If it's faster, let's do it...

#48

Dries - January 3, 2010 - 11:05
Status:reviewed & tested by the community» fixed

Committed to CVS HEAD. Thanks!

#49

Gábor Hojtsy - January 3, 2010 - 14:28
Version:7.x-dev» 6.x-dev
Status:fixed» patch (to be ported)

Ok, let's port this updated approach to D6.

#50

Arancaytar - January 3, 2010 - 17:06
Status:patch (to be ported)» needs review

Merged #43 and #46 together.

AttachmentSizeStatusTest resultOperations
common-info-colon-424372-50-D6.patch911 bytesIgnoredNoneNone
 
 

Drupal is a registered trademark of Dries Buytaert.