Apache / PHP on Windows crashes with regex

I found that the following PHP code crashes when running on a Windows Apache server:

<?php $test = "0,4,447,11329,316,415,142,5262,6001,9527,11259,11236,1140,9770,9177,9043,11090,268,5270,9907,9196,10226,". "9399,1476,9368,6929,1659,11074,10869,8774,739,11344,10482,6399,8910,8997,11198,137,10148,10371,5128,767,2483,". "211,9973,10726,9299,778,11157,9497,275,9418,11141,241,5288,11324,776,10960,9289,7944,222,10686,11428,9723,". "10615,11399,9869,9083,10180,10043,9957,9387,9215,8869,9667,10174,10902,6607,9282,1259,395,10411,152,9344,8949,". "10923,8976,11042,11519,10704,10979,216,10044,9201,1721,5831,881,9721,1757,11054,1335,6151,9526,9081,111,498,". "2960,438,5313,206,318,10820,8192,6039,9161,11012,1717,1360,10757,4314,11280,9647,9346,10546,11006,9553,10365,". "6148,10565,4532,2776,4124,8853,6145,478,4539,540,9981,726,7186,11122,324,10524,1139,7900,9581,6869,1724,10851,". "10059,10018,11032,1290,3818,782,796,917,8740,6935,11439,10799,10948,249,2068,8778,6289,295,2766,9425,791,309,". "4753,10418,771,260,10835,10441,6434,10164,10475,10842,9013,11224,2247,8972,2141,2078,2152,475,9077,6291,10285,". "8067,753,6660,10889,431,2503,6007,9180,810,11447,2461,3689,7104,10150,10921,895,10598,747,10570,305,4497,11055,". "11496,10938,10722,8761,10086,11482,6780,6685,6918,10286,10659,9996,4074,9118,907,5192,283,2230,8884,6966,". "8820,8132,3598,9599,6796,11257,7049,5992,8637,4168,9017,7950,7165,10721,10037,1071,8044,759,11429,6380,". "10239,1593,9455,9704,10357,6737,2958,4051,9754,6564,11407,8716,7485,1528,6857,7406,9579,7259,1609,7820,". "4448,10289,1123,7005,8123,9316,914,9655,5280,9710,7822,510,10795,10476,8706,6160,8248,6978,9300,10643,". "7106,10250,519,7860,4733,904,8773,4714,8695,8633,6105,3312,11548,9580,10389,4886,4587,513,8485,4606,". "6471,581,526,637,3523,3772,3153,9336,9120,7633,3755,10087,524,10015,8563,556,1230,570,3652,569" .",8473,10209,3886,573,5363,4715,3865,9452,1218,7066,575,577,4724,7655" ; $hest = preg_match('/^\d+(?:,\d+)+$/', $test); var_dump($hest); ?> 

Interestingly, the code works if the line is a little shorter - if I comment on the last part of the line, the code works and works as expected.

However, since the code is presented here, the code causes Apache to crash and respawn - the error is not logged. If I try to run the code directly through PHP, it works as expected, so the problem is somehow related to Apache.

I experimented with the parameter "pcre.recursion_limit" and found that if I lowered it to 689 it would not die, but instead, the call to preg_match () failed with PREG_RECURSION_LIMIT_ERROR. For higher values, pcre.recursion_limit Apache dies.

Apache 2.2.11 PHP 5.3.0

I also tested this on a Debian server, where I DO NOT see the error, and with different versions of PHP and Apache on Windows, where the error occurs as described above, so it seems that this could be due to Windows.

Does anyone have this? I would really like to say something!

UPDATE: I am due to an “error” in Apache for Windows - well, actually it is not an error, but it seems that Apache is compiled with a little stacking, and this causes this error in PCRE when PHP uses it. See http://bugs.php.net/bug.php?id=47689

+6
windows php regex apache
source share
4 answers

It is always useful to lower pcre.recursion_limit because a high value can damage the process stack by default (see http://php.net/manual/en/pcre.configuration.php ) - this is exactly what happens with your installation mod_php. Since preg functions do not throw an error when reaching the recursion / backtracking limits, it may be useful to have a shell like

 function match($re, $text) { preg_match($re, $text, $m); if(preg_last_error()) trigger_error("preg: " . preg_last_error()); return $m; } 

At the very least, this allows you to find out when something goes wrong.

Also, try to simplify your templates whenever possible, for example /^\d[\d,]*\d$/ does the same as above, but with zero recursion.

+3
source share

Enlarge the Apache stack and the problem goes away, or use httpd config to enlarge it.

Most Apache builds have a too small stack size, while we have a normal one for PHP builds. This explains why the same expressions will work in the CLI and not in Apache (the stack is for each process and the process belongs / is defined by Apache).

+1
source share

An accident usually means that you are caught in a PHP error. This happens from time to time. If you cannot upgrade your PHP installation, you will have to rewrite your code. In any case, a high level of recursion suggests that you should not use regular expressions, or at least you should first split the input string into smaller parts.

0
source share

Thanks so much for this post. This solved my problem.

The config for the Apache stack on Windows is the reason. A quick way to increase the size of the Apache stack is to use the ThreadStackSize directive in the Apache configuration ( http://httpd.apache.org/docs/2.2/mod/mpm_common.html#ThreadStackSize ).

It might look like this:

 <IfModule mpm_winnt_module> ThreadStackSize 8*1024*1024 </IfModule> 

It sets the stack size to 8 MB, just like the default value on Linux.

(Thanks for https://bugs.php.net/bug.php?id=47689 )

0
source share

All Articles