During a cache clear, .info files are parsed by drupal_parse_info_format using preg_match_all. The expression used triggers a bug that exists in PHP5.3.13 (PCRE version 8.12), at least under Windows. The same .info files work fine on Windows using PHP5.2.11 (PCRE version 7.8). It works fine on Ubuntu with PHP 5.3.2 (PCRE 7.8). The PHP/PCRE versions are documented here.
To reproduce the problem, download the AddToAny module and flush the cache. Apache (2.2.22) will reset. AddToAny is by no means the only module which triggers this bug.
You can reproduce it directly using devel's Execute PHP block:
print_r(drupal_parse_info_format('sites/all/modules/addtoany/addtoany.info')); // or ...info_file for Drupal 6
It is difficult to tell exactly what is causing the bug, except that I believe it is related to the positive look-back assertions in the regular expression:
if (preg_match_all('
@^\s* # Start at the beginning of a line, ignoring leading whitespace
((?:
[^=;\[\]]| # Key names cannot contain equal signs, semi-colons or square brackets,
\[[^\[\]]*\] # unless they are balanced and not nested
)+?)
\s*=\s* # Key/value pairs are separated by equal signs (ignoring white-space)
(?:
("(?:[^"]|(?<=\\\\)")*")| # Double-quoted string, which may contain slash-escaped quotes/slashes
(\'(?:[^\']|(?<=\\\\)\')*\')| # Single-quoted string, which may contain slash-escaped quotes/slashes
([^\r\n]*?) # Non-quoted string
)\s*$ # Stop at the next end of a line, ignoring trailing whitespace
@msx', $data, $matches, PREG_SET_ORDER)) {
The offending line from addtoany.info (all fits on one line):
description = "Helps readers share, bookmark, and email your articles and pages using any service, such as Facebook, Twitter, Google+, StumbleUpon, and over 100 more using the <a href='http://share.lockerz.com/' target='_blank'>Lockerz Share / AddToAny</a> widget."
Shortening the line makes it work, as does removing the quotes. This may be related to #618400: Cannot install google_auth, getting a "connection was reset" error in the Google Analytic module, where a multi-line description caused a crash, which was fixed by adjusting the .info file, rather than addressing the underlying problem.
Clearly the regular expression *should* work, but it it doesn't work with the recent PCRE version, then I would argue that as a practical matter, Drupal is broken.
I think the easiest way to fix this is simply to remove the two look-back assertions:
|(?<=\\\\)"
|(?<=\\\\)\'
The only difference is in how an improperly-formatted .info file would be processed. Currently something like the following would be processed as a non-quoted string ("Joe said, "hi there!""). If we remove the look-back assertion, it would be treated as a quoted string (Joe said, "hi there!"). Not clearly worse; probably better.
key = "Joe said, "hi there!""
I am unclear why more people aren't reporting this. Maybe no one is using current releases of PHP5.3. Or maybe it only happens on Windows. But given that Drupal completely crashes (connection reset), and that it is caused by multiple modules, for those unlucky folks with configuration that trigger it, it is a major -- if not critical -- bug.
ADDENDUM:
Report to PCRE: Bug 1338
| Comment | File | Size | Author |
|---|---|---|---|
| #7 | drupal_parse_info_format_crash_windows-1917530-6.patch | 942 bytes | dagomar |
Comments
Comment #0.0
danchadwick commentedEdited html to prevent example links from being shown as links, rather than raw html
Comment #1
catchDowngrading this to normal since it only affects a specific PCRE version.
Comment #2
danchadwick commented@catch - PCRE 8.12 is, according to the PHP manual, the most recent version of PCRE for PHP 5.3. Having re-read the descriptions of priority in the handbook, I think this bug meets the definition of critical, much less major or normal. I can see a lower priority if the user could simply upgrade to a later PCRE to avoid the bug. But they can't. They actually have to down-grade to an earlier version, apparently. In my case, I don't have a built PHP 5.3 environment with an older PCRE. I would have to go back to PHP 5.2, which has other compatibility issues for me.
I heard back from the PCRE maintainer, and unfortunately he is not interested in testing 8.12, since it is a couple of years old. And yet as PHP users, we don't directly control the version of PCRE we run.
This is a difficult problem to track down, because there is no PHP message. Apache simply resets the connection. Without good debugging tools, a user would have a very difficult time figuring out what is wrong and working around it (by either editing the RegEx expression or the .info file(s)).
As more servers -- development, shared, VPS and otherwise -- start going to PHP 5.3, I think we will see this bug happen more frequently.
Comment #3
chx commentedI will take a look as time permits.
Comment #4
drzraf commentedis there any reason
parse_ini_fileis not used ?Comment #5
chx commentedyes, there is.
Comment #6
dagomar commentedThis problem still persists, no solution yet?
Comment #7
dagomar commentedI created a patch for the suggestion in the issue summary:
I'm not sure if that is a permanent solution, but at least it will help the developers running Windows to get on with their work.
Comment #7.0
dagomar commentedAdded link to PCRE bug report
Comment #8
ITWest-jg commentedI get this error - no apache2.4 error message and no PHP5.5.10 (Windows 7) error message. Took me a while to find this page ;)
Comment #9
danchadwick commentedComment #10
chx commented